Giter VIP home page Giter VIP logo

websocket_server's Introduction

WebSocket Server

A conforming server implementation of the WebSocket standard as a module for PureBasic.

Features:

  • Supports unfragmented and fragmented binary and text frames.
  • Callback based for easy use and low latency.
  • The module combines fragment frames automatically, this is on by default and can be turned off in case the application needs to handle fragmentation itself.
  • Built in handling of control frames (ping, disconnect).
  • Passes nearly all of Autobahn|Testsuite test cases (289 / 303).

Not supported:

  • Any sort of compression. This will not hurt compatibility, as compression is optional.
  • Automatic splitting of frames into fragments, but this can be done by the application if needed.
  • Any WebSocket extensions.
  • TLS. Best is to use a webserver (like Caddy) and setup a reverse proxy to the WebSocket server. If you need to supply static files (html, js), this is the preferred way anyways.

Usage (Easy: Polling for events)

The easier (but slower) method of using this WebSocket server is to poll for events. Even though the server uses threads internally, you don't have to worry about race conditions, deadlocks and so on. All you need to do is to call WebSocket_Server::Event_Callback(*Server, *Callback) from your own main loop, this will call your event handling function that you have passed as the *callback parameter in the same context as your main loop.

Open a WebSocket-Server:

*Server = WebSocket_Server::Create(8090)

Receive events as callback:

Procedure WebSocket_Event(*Server, *Client, Event, *Event_Frame.WebSocket_Server::Event_Frame) ; no need to worry about mutexes as this call is coming from your main loop
  Select Event
    Case WebSocket_Server::#Event_Connect
      PrintN(" #### Client connected: " + *Client)
      
    Case WebSocket_Server::#Event_Disconnect
      PrintN(" #### Client disconnected: " + *Client)
      ; !!!! From the moment you receive this event *Client must not be used anymore !!!!
      
    Case WebSocket_Server::#Event_Frame
      PrintN(" #### Frame received from " + *Client)
      
      ; #### OpCode is the type of frame you receive.
      ; #### It's either Text, Binary-Data, Ping-Frames or other stuff.
      ; #### You only need to care about text and binary frames.
      Select *Event_Frame\Opcode
        Case WebSocket_Server::#Opcode_Ping
          PrintN("      Client sent a ping frame")
        Case WebSocket_Server::#Opcode_Text
          PrintN("      Text received: " + PeekS(*Event_Frame\Payload, *Event_Frame\Payload_Size, #PB_UTF8|#PB_ByteLength))
        Case WebSocket_Server::#Opcode_Binary
          PrintN("      Binary data received")
          ; *Event_Frame\Payload contains the data, *Event_Frame\Payload_Size is the size of the data in bytes.
          ; !!!! Don't use the Payload after you return from this callback. If you need to do so, make a copy of the memory in here. !!!!
      EndSelect
      
  EndSelect
EndProcedure

Your main loop:

Repeat
  ; Other stuff
  While WebSocket_Server::Event_Callback(*Server, @WebSocket_Event())
  Wend
  ; Other stuff
ForEver

Send a text-frame:

WebSocket_Server::Frame_Text_Send(*Server, *Client, "Hello Client!")

Send a binary-frame:

WebSocket_Server::Frame_Send(*Server, *Client, #True, 0, WebSocket_Server::#Opcode_Binary, *Data, Data_Size)

Close and free a WebSocket-Server:

Free(*Server)

Usage (Advanced: Threaded callback)

This is similar to the method above, but instead of calling WebSocket_Server::Event_Callback() you set your event handler callback when you create your WebSocket server. Your event handler will be called as soon as any event occurs. But as the callback is called from a thread, you have to make sure everything in your event handler is thread-safe with the rest of your program. This mode has better performance, less latency and uses less resources. But it may cause problems like deadlocks or race conditions in your code if you use it wrong.

To make it clear, you only have to make sure that all your resources/lists/variables/... that you access from the event handler function are thread-safe with the rest of your program. But you can still send websocket message from any thread or the event handler itself without using mutexes, as the functions of this module are thread-safe.

Open a WebSocket-Server:

*Server = WebSocket_Server::Create(8090, @WebSocket_Event())

Receive events as callback:

Procedure WebSocket_Event(*Server, *Client, Event, *Event_Frame.WebSocket_Server::Event_Frame)
  Select Event
    Case WebSocket_Server::#Event_Connect
      PrintN(" #### Client connected: " + *Client)
      
    Case WebSocket_Server::#Event_Disconnect
      PrintN(" #### Client disconnected: " + *Client)
      ; !!!! From the moment you receive this event *Client must not be used anymore !!!!
      
    Case WebSocket_Server::#Event_Frame
      PrintN(" #### Frame received from " + *Client)
      
      ; #### OpCode is the type of frame you receive.
      ; #### It's either Text, Binary-Data, Ping-Frames or other stuff.
      ; #### You only need to care about text and binary frames.
      Select *Event_Frame\Opcode
        Case WebSocket_Server::#Opcode_Ping
          PrintN("      Client sent a ping frame")
        Case WebSocket_Server::#Opcode_Text
          PrintN("      Text received: " + PeekS(*Event_Frame\Payload, *Event_Frame\Payload_Size, #PB_UTF8|#PB_ByteLength))
        Case WebSocket_Server::#Opcode_Binary
          PrintN("      Binary data received")
          ; *Event_Frame\Payload contains the data, *Event_Frame\Payload_Size is the size of the data in bytes
          ; !!!! Don't use the Payload after you return from this callback. If you need to do so, make a copy of the memory in here. !!!!
      EndSelect
      
  EndSelect
EndProcedure

Send a text-frame:

WebSocket_Server::Frame_Text_Send(*Server, *Client, "Hello Client!")

Send a binary-frame:

WebSocket_Server::Frame_Send(*Server, *Client, #True, 0, WebSocket_Server::#Opcode_Binary, *Data, Data_Size)

Close and free a WebSocket-Server:

Free(*Server)

Example

Here is an example chat application made with WebSockets.

Dadido3/WebSocket_Server/master/HTML/Chat_Client.html

This example needs to connect to a WebSocket server. If it doesn't connect to my server you can run your own local server. For this you just have to compile and run Example_Chat_Server.pb.

websocket_server's People

Contributors

dadido3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.