Page 1 of 3

WebSocket Server

Posted: Sun Feb 08, 2015 7:24 pm
by Dadido3
Hi,

Here's a WebSocket-Server module i wrote over the last days.
It can be used to establish a continuous, bidirectional connection between a purebasic program and javascript running in a website.

Tested OSes:
  • Windows 7 x64
  • Others should also work.
Example:
The repository contains a chat-application as an example.
The server is written in PureBasic and the client in HTML and JavaScript.
I have currently running a server and the client should automatically connect to it. Click here to open the client.

Open a WebSocket-Server:

Code: Select all

*Server = WebSocket_Server::Create(8090, @WebSocket_Event())
Receive events as callback:

Code: Select all

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 the *Client can not be used anymore !!!!
      
    Case WebSocket_Server::#Event_Frame
      PrintN(" #### Frame received from " + *Client)
      
      ; #### OpCode is the type of frame you receive.
      ; #### 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
          Debug "Client sent a ping frame"
        Case WebSocket_Server::#Opcode_Text
          Debug "Text received: " + PeekS(*Event_Frame\Payload, *Event_Frame\Payload_Size, #PB_UTF8|#PB_ByteLength)
        Case WebSocket_Server::#Opcode_Binary
          ; *Event_Frame\Payload contains the data, *Event_Frame\Payload_Size is the size of the data in bytes
      EndSelect
      
  EndSelect
EndProcedure
Send a text-frame:

Code: Select all

WebSocket_Server::Frame_Text_Send(*Server, *Client, "Hello Client!")
Close and free a WebSocket-Server:

Code: Select all

Free(*Server)
Files: Have fun with it.

Re: WebSocket Server

Posted: Mon Feb 09, 2015 12:14 am
by falsam
Thanks for sharing. The question is : How to install the server in a hosting company?

Re: WebSocket Server

Posted: Mon Feb 09, 2015 12:52 am
by Dadido3
falsam wrote:How to install the server in a hosting company?
Well, it wouldn't work on a shared webserver just for webhosting.
You would atleast need a VPS (Virtual Private Server) with linux or windows, but they aren't much more expensive than a shared webserver.
If you have something like that you just need to run your purebasic application with the WebSocket-Server on it.

Or you could use a dynamic dns and run the WebSocket-Server at home...

But there are also some usecases where you don't need to rent a server and can run it locally:
  • Create a webinterface for your software. You can access the webinterface from any mobile device with a modern webbrowser.
  • Communicate with Websites in the WebGadget of purebasic. You could send data to it and it would render nice charts in realtime. (e.g. via http://d3js.org/)
  • And other things.

Re: WebSocket Server

Posted: Mon Feb 09, 2015 11:31 am
by Fred
This is great code, thanks for sharing !

Re: WebSocket Server

Posted: Mon Feb 09, 2015 3:30 pm
by Rings
windows x64 compiles fine and runs ok so far.

windows x86 compiles with a error in line 437
in module websocket_server.pbi:

The specified number is incorrect for '<<' or '>>' (must be 0-31)

(BITSHIFTING !!)

Re: WebSocket Server

Posted: Mon Feb 09, 2015 5:22 pm
by Dadido3
Hi,

yeah i should have tested it under x86...
It's fixed, i changed the conversion of the byteorder to use memory operations.
So now it's a little bit faster.

Any other strange stuff which isn't working as expected?

Re: WebSocket Server

Posted: Tue Feb 10, 2015 11:57 am
by holzhacker
He works on Ubuntu 14.04.1 LTS (64-bit), compiled in PureBasic 5.31 (x64).

Congratulations !!! 8)

Re: WebSocket Server

Posted: Tue Feb 10, 2015 1:24 pm
by bbanelli
Should change Executable format to Console to work on OS X.

Image

Great job Dadido3, very neat usage of all PB's resources and abilities!

Re: WebSocket Server

Posted: Thu Feb 12, 2015 7:23 pm
by RichAlgeni
It's beautiful!

Re: WebSocket Server

Posted: Tue May 26, 2015 12:17 pm
by Thorium
Thank for the code.
Will you add TSL?

Re: WebSocket Server

Posted: Tue May 26, 2015 2:18 pm
by Justin
It is based on the synchronous pb functions? or did you use the api and go asynchronous?

Re: WebSocket Server

Posted: Wed Jun 17, 2015 3:32 pm
by HanPBF
Downloaded, started PB, startet HTML...
...just worked :D

Thanks a lot for this great code!!!!

PB 5.50 b1; WebSocket Server; fingerPrint function;

Posted: Thu Jun 16, 2016 2:04 pm
by HanPBF
WebSocket server does not work anymore

Code: Select all

; #### Generate the SHA1
 *Temp_Data_2 = AllocateMemory(20)
Temp_SHA1.s = Fingerprint(*Temp_Data, Temp_String_ByteLength, #PB_Cipher_SHA1) ; error: The specified cipher plugin is missing
 For i = 0 To 19
  PokeA(*Temp_Data_2+i, Val("$"+Mid(Temp_SHA1, 1+i*2, 2)))
Next
Error: "The specified cipher plugin is missing"

There are some hints to the fingerprint function in this forum; but I could not puzzle it out.
Is another function needed? Which use*Fingerprint() needs to be used?


Any help?


Thanks a lot in advance!

Regards!

Re: WebSocket Server

Posted: Thu Jun 16, 2016 2:07 pm
by HanPBF
o.k. solved...

Code: Select all

 Temp_SHA1.s = Fingerprint(*Temp_Data, Temp_String_ByteLength, #PB_Cipher_CRC32)

Re: WebSocket Server

Posted: Thu Jun 16, 2016 2:55 pm
by Dadido3
Hi,

it would be strange if it works with CRC32. It may compile, but you shouldn't be able to connect.
Beside that it's easier to use StringFingerprint(...) as you can define the string encoding there.

Even though i didn't mentioned it, i updated the include about 8 months ago.
The easiest way is just to use the new version, as it is compatible with the newest PB version.
Justin wrote:It is based on the synchronous pb functions? or did you use the api and go asynchronous?
I don't know if you still care, but it's using PB's built in network functions. But the network code is running in its own thread, so the network logic is only blocked as long as the callback is executed.
If you don't want to serve several thousand clients it should work fine.
Thorium wrote:Will you add TSL?
It's planned, but i can't say when i'll add it.

Edit:
If TLS is needed you can use a webserver as proxy. For NGINX this may be helpful: http://stackoverflow.com/questions/1210 ... le-ssl-wss. But i haven't tried it.