Monthly Target: $400 Donations: $140
 35% 

Notices

[DEV] WebSocket Server - Direct connection between webbrowser and gameserver


Post New Thread Reply   
 
Thread Tools Display Modes
Author
Peace-Maker
SourceMod Plugin Approver
Join Date: Aug 2008
Location: Germany
Plugin ID:
2900
Plugin Version:
1.2
Plugin Category:
Technical/Development
Plugin Game:
Any
Plugin Dependencies:
    Servers with this Plugin:
    29 
    Plugin Description:
    WebSocket protocol implementation to create a server via sourcemod (Version 1.2, Updated 12.01.2017)
    Old 04-11-2012 , 20:33   [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #1

    WebSocket
    A WebSocket protocol implementation to create a direct connection between webbrowsers and gameservers.

    WebSocket is a protocol designed to create a realtime connection between webbrowsers and webservers via javascript to exchange asynchronous information without reloading the page or requiring a client poll/page refresh.
    This plugin provides an interface to create such an WebSocket server via SourceMod. Now you're able to do a live webchat seeing ingame events or even following the game in your browser like SourceTV or exchange whatever information you want.

    This plugin doesn't open a server by itself and doesn't do much alone. It's a base for other plugins to implement fancy stuff without knowing the actual protocol.

    Code is on github!
    https://github.com/peace-maker/sm-websocket

    Acknowledgements
    This implementation follows the draft version 17 of the websocket protocol specifications, except:
    • Only partial support for fragmented messages. The plugin can handle incoming fragmented messages and reassemble them, but doesn't split big outgoing messages.
    • One websocket per plugin. Unlimited amount of connections though.
    • Multiple plugins opening a websocket on the same ip:port combo both share the WebSocket handle. The socket is only closed, if all plugins using it closed it. If one plugin closes the socket, the forwards are no longer fired, but the socket is still open until the last plugin closes it.
    • You can't use CloseHandle on websocket handles, since this is implemented in sourcepawn, which doesn't support adding "Handle" types. Use Websocket_Close instead.
    • You should always close your master websocket in OnPluginEnd().
    • This adapts to HTTP which is using TCP for connection management. You'll need to have the TCP port unblocked in your firewall to allow reading and writing.
    Plugin Interface

    Natives

    PHP Code:
    /**
     * Creates a websocket server which listens on the supplied ip:port combination.
     *
     * @param sHostName        The IP to bind to.
     * @param iPort            The port to listen on
     * @param inc            The incoming child connection callback
     * @param we            The error callback
     * @return                A WebsocketHandle or INVALID_WEBSOCKET_HANDLE on error.
     */
    native WebsocketHandle:Websocket_Open(const String:sHostName[], iPortWebsocketIncomingCB:incWebsocketErrorCB:weWebsocketCloseCB:clo);

    /**
     * Hooks child socket's events
     *
     * @param childwebsocket    The child websocket to hook.
     * @param recv                Data receive callback
     * @param disc                The disconnect callback
     * @param we                The error callback
     * @return                    True if child socket was hooked, false otherwise
     */
    native bool:Websocket_HookChild(WebsocketHandle:childwebsocketWebsocketReceiveCB:recvWebsocketDisconnectCB:discWebsocketErrorCB:we);

    /**
     * Hooks child socket's readystate changes
     *
     * @param childwebsocket    The child websocket to hook.
     * @param readystate               ReadyState change callback
     * @return                    True if child socket was hooked, false otherwise
     */
    native bool:Websocket_HookReadyStateChange(WebsocketHandle:childwebsocketWebsocketReadyStateChangedCB:readystate);

    /**
     * Sends text or binary data through the websocket
     *
     * @param childwebsocket    The child websocket to send to
     * @param type                The datatype SendType_Text or SendType_Binary
     * @param sPayLoad             The data to send
     * @param dataSize            If set, it's used as maxlength. Useful for binary data where \0 might be used before the end of the data.
     * @return                    True if child socket was hooked, false otherwise
     */
    native bool:Websocket_Send(WebsocketHandle:childwebsocketWebsocketSendType:type, const String:sPayload[], const dataSize=-1);

    /**
     * Gets a child websocket's readyState.
     *
     * @param childwebsocket    The child websocket
     * @return                    The readyState
     */
    native WebsocketReadyState:Websocket_GetReadyState(WebsocketHandle:childwebsocket);

    /**
     * Unhooks a child socket's events: If there's no plugin listening anymore, the socket is closed.
     *
     * @param childwebsocket    The child websocket
     * @noreturn
     */
    native Websocket_UnhookChild(WebsocketHandle:childwebsocket);

    /**
     * Closes a listening master socket, created with Websocket_Open.
     * Note: The socket will still be open, if there are more plugins using it.
     * 
     * Call this in OnPluginEnd()!
     *
     * @param websocket    The master websocket
     * @noreturn
     */
    native Websocket_Close(WebsocketHandle:websocket); 
    Requirements
    Compiling dependencies


    Thanks to
    • sfPlayer and his Socket extenstion
    • SirLamer - Base64 include

    Changelog
    Spoiler


    Server owners only need the websocket.smx in their plugins folder and the Socket extension installed. This plugin won't compile on the forum due to it's custom include requirements.

    Attached Files
    File Type: sp Get Plugin or Get Source (websocket.sp - 19 views - 48.1 KB)
    File Type: smx websocket.smx (22.2 KB, 20 views)
    File Type: inc websocket.inc (6.2 KB, 337 views)
    __________________

    Last edited by Peace-Maker; 01-12-2017 at 22:56. Reason: Released version 1.2
    Peace-Maker is offline
    Peace-Maker
    SourceMod Plugin Approver
    Join Date: Aug 2008
    Location: Germany
    Old 04-11-2012 , 20:33   Re: [DEV] WebSocket Server
    Reply With Quote #2

    Example

    Simple Webchat
    HTML based off phpwebsocket's client.html

    Creating a connection and listening for events in javascript.
    Replace the ip and port with the ones you're using in your websocket_test.sp.
    PHP Code:
    var socket;

    function 
    init(){
      
      var 
    host "ws://192.168.1.100:12345/";
      try{
        if(!
    window.WebSocket)
            
    socket = new MozWebSocket(host);
        else
            
    socket = new WebSocket(host);
        
    log('WebSocket - status '+socket.readyState);
        
    socket.onopen    = function(msg){ log("Welcome - status "+this.readyState); };
        
    socket.onmessage = function(msg){ log("Received: "+msg.data); };
        
    socket.onerror = function(msg){ log("Error!"); };
        
    socket.onping = function(msg){ log("Received ping: "+msg.data); };
        
    socket.onpong = function(msg){ log("Received pong: "+msg.data); };
        
    socket.onclose   = function(msg){ log("Disconnected - status "+this.readyState+" Code: "+msg.code+". Reason:"+msg.reason+" - wasClean: "+msg.wasClean); };
      }
      catch(
    ex){ log('Error: '+ex); }
      $(
    "msg").focus();

    The websocket_test.sp plugin just creates a websocket on port 12345 and listenes for new connections. If some client sends anything to the server, it relays it to all other connected clients as well as to the game chat. Simple as that ;)

    You need to strip the .txt suffix off the client.html. The forum won't let me upload .html files.

    SourceTV2D
    This is the reason why this plugin was made initially. It's still not finished at all and i'm no javascript pro, so the code isn't easy to read, but it works to some extend.
    You could preview what's possible with WebSockets over at http://sourcetv2d.wcfan.de/ . It's a realtime stream off our deathmatch server.

    Be warned, this isn't stable at all and you should only mess with it for testing and improving reasons. Please post any additions you do
    You have to edit the index.html in order to set the right IP of your gameserver to connect to.
    Attached Files
    File Type: txt client.html.txt (2.1 KB, 369 views)
    File Type: zip sourcetv2d.zip (561.5 KB, 347 views)
    File Type: sp Get Plugin or Get Source (websocket_sourcetv2d.sp - 234 views - 20.3 KB)
    File Type: sp Get Plugin or Get Source (websocket_test.sp - 311 views - 3.6 KB)
    __________________

    Last edited by Peace-Maker; 01-12-2017 at 23:02. Reason: Updated examples with callback changes of version 1.1
    Peace-Maker is offline
    asherkin
    SourceMod Developer
    Join Date: Aug 2009
    Location: OnGameFrame()
    Old 04-11-2012 , 21:30  
    Reply With Quote #3

    This is really sweet, nice work.
    __________________
    asherkin is offline
    McFlurry
    Veteran Member
    Join Date: Mar 2010
    Location: RemoveEdict(0);
    Old 04-11-2012 , 21:56   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #4

    Very awesome.
    __________________
    McFlurry is offline
    Send a message via Skype™ to McFlurry
    GoD-Tony
    Veteran Member
    Join Date: Jul 2005
    Old 04-12-2012 , 14:23   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #5

    Nice.

    Hopefully I'll get a chance to test this out myself!
    __________________
    GoD-Tony is offline
    raydan
    Senior Member
    Join Date: Aug 2006
    Old 04-13-2012 , 10:17   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #6

    Peace-Maker why you got my sourcetv2d
    __________________
    too slow
    raydan is offline
    Peace-Maker
    SourceMod Plugin Approver
    Join Date: Aug 2008
    Location: Germany
    Old 04-13-2012 , 14:02   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #7

    Quote:
    Originally Posted by raydan View Post
    Peace-Maker why you got my sourcetv2d
    You didn't seem to want to release yours as you compressed the javascript. Still didn't change your mind?
    __________________
    Peace-Maker is offline
    redwerewolf
    r3dw3r3w0lf
    Join Date: Sep 2009
    Old 04-13-2012 , 14:14   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #8

    The only issue I see with that script that shows players live is that they could cheat with it. They can see anyone on the map at anytime with just a quick look and know where they're at.

    Note: I mean the example and I know you said it's not perfect but it's a worry of mine. lol
    __________________
    I no longer do Sourcemod commissions, don't message me please.

    Last edited by redwerewolf; 04-13-2012 at 14:16.
    redwerewolf is offline
    Nomarky
    SourceMod Donor
    Join Date: Sep 2007
    Old 04-13-2012 , 15:37   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #9

    Quote:
    Originally Posted by r3dw3r3w0lf View Post
    The only issue I see with that script that shows players live is that they could cheat with it. They can see anyone on the map at anytime with just a quick look and know where they're at.

    Note: I mean the example and I know you said it's not perfect but it's a worry of mine. lol
    Maybe a small delay (if technically possible) would deal with that?
    Nomarky is offline
    Peace-Maker
    SourceMod Plugin Approver
    Join Date: Aug 2008
    Location: Germany
    Old 04-13-2012 , 15:46   Re: [DEV] WebSocket Server - Direct connection between webbrowser and gameserver
    Reply With Quote #10

    Currently the plugin denys connections from ips which are already connected and closes them, if a player who's currently watching in sourcetv2d, joins.

    I thought of a buffer to store messages for x seconds until sending them out, but it's easier to test in realtime ;)
    __________________
    Peace-Maker is offline
    Reply


    Thread Tools
    Display Modes

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off

    Forum Jump


    All times are GMT -4. The time now is 14:25.


    Powered by vBulletin®
    Copyright ©2000 - 2017, vBulletin Solutions, Inc.
    Theme made by Freecode