Page 1 of 1

WebSocket Chatclient

Posted: Fri Oct 27, 2017 4:43 pm
by Dirk Geppert
I hope its a good start for someone, to dig into the websocket technology.

For this example, you'll need the WebSocket_Server from Dadido3.
http://www.purebasic.fr/english/viewtop ... 12&t=61606

You can download the source from here: https://github.com/Dadido3/WebSocket_Se ... master.zip
Just compile and run the Example_Chat_Server.pb

Thanks to Peter, for the socket procs: http://forums.spiderbasic.com/viewtopic.php?f=8&t=321

Code: Select all

Structure Chat_Message
  Type.s
  Author.s
  Message.s
  Timestamp.q
EndStructure

Structure Chat_Username_Change
  Type.s
  Username.s
EndStructure

Structure Chat_Userlist
  Type.s
  
  List Username.s()
EndStructure

Enumeration FormWindow
  #hWnd
EndEnumeration

Enumeration FormGadget
  #S_CHAT
  #B_SEND
  #LI_CHAT
  #S_USER
  #T_USER
  #T_MESSAGE
EndEnumeration


Procedure OpenhWnd(x = 0, y = 0, width = 414, height = 300)
  OpenWindow(#hWnd, x, y, width, height, "", #PB_Window_BorderLess)
  StringGadget(#S_CHAT, 10, 160, 310, 30, "")
  ButtonGadget(#B_SEND, 10, 220, 390, 50, "Send")
  ListIconGadget(#LI_CHAT, 10, 10, 390, 120, "User", 100)
  AddGadgetColumn(#LI_CHAT, 1, "Message", 250)
  StringGadget(#S_USER, 330, 160, 70, 30, "")
  TextGadget(#T_USER, 330, 140, 70, 20, "Name")
  TextGadget(#T_MESSAGE, 10, 140, 70, 20, "Message")
EndProcedure


Declare Send_Message()
Declare Send_UserName()

Procedure doSend(message.s)
  Debug "Sending: " + message
  ! websocket.send(v_message);
EndProcedure

Procedure onOpen(evt)
  Debug "onOpen()"
  SetGadgetText(#B_SEND, "Send")
  DisableGadget(#B_SEND, #False)
  Send_UserName()
EndProcedure

Procedure onClose(evt)
  Debug "onClose"
  SetGadgetText(#B_SEND, "No connection")
  DisableGadget(#B_SEND, #True)
EndProcedure

Procedure onMessage(evt)
  Protected M.Chat_Message
  Protected JSONID.i
  Protected MessageFromWs.s
  
  ! v_messagefromws = v_evt.data;
  
  Debug "MessageFromWs: " + MessageFromWs
    
  JSONID = ParseJSON(#PB_Any, MessageFromWs)
  If JSONID
    ExtractJSONStructure(JSONValue(JSONID), @M, Chat_Message)
    FreeJSON(JSONID)
  EndIf
  
  If M\Type = "Message"
    AddGadgetItem(#LI_CHAT, 0, M\Author + Chr(10) + M\Message)
  EndIf
  
EndProcedure

Procedure onError(evt)
  Debug "onError()"
  ; Debug evt
  Debug "-------"
EndProcedure

Procedure initWebSocket(wsuri.s)
  ! websocket = new WebSocket(v_wsuri);
  ! websocket.onopen = function(evt) { f_onopen(evt) };
  ! websocket.onclose = function(evt) { f_onclose(evt) };
  ! websocket.onmessage = function(evt) { f_onmessage(evt) };
  ! websocket.onerror = function(evt) { f_onerror(evt) };
EndProcedure

Procedure Send_UserName ()
  Protected U.Chat_Username_Change
  Protected JSONID.i
  
  U\Username = GetGadgetText(#S_USER)
  U\Type = "Username_Change"
  
  JSONID = CreateJSON(#PB_Any)
  
  If JSONID <> 0
    InsertJSONStructure(JSONValue(JSONID), @U, Chat_Username_Change)
    doSend( ComposeJSON(JSONID))
    FreeJSON(JSONID)
  EndIf
  
EndProcedure  

Procedure Send_Message ()
  Protected M.Chat_Message
  Protected JSONID.i
  
  M\Author = GetGadgetText(#S_USER)
  M\Message = GetGadgetText(#S_CHAT)
  M\Timestamp = Date()
  M\Type = "Message"
  
  JSONID = CreateJSON(#PB_Any)
  
  If JSONID <> 0
    InsertJSONStructure(JSONValue(JSONID), @M, Chat_Message)
    doSend( ComposeJSON(JSONID))
    FreeJSON(JSONID)
  EndIf
  
EndProcedure

OpenhWnd()
DisableGadget(#B_SEND, #True)
BindGadgetEvent(#B_SEND, @Send_Message(), #PB_EventType_LeftClick)
SetGadgetText(#S_USER, "Guest_" + Str(Random(100)))

initWebSocket("ws://127.0.0.1:8090")

Re: WebSocket Chatclient

Posted: Mon Oct 30, 2017 4:35 pm
by tj1010
A more _likely to work with all hosts_ method is throttled polling.