Raised This Month: $12 Target: $400
 3% 

Solved Communicating with socket.io using sourcemod and socket


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Blowst
Senior Member
Join Date: Feb 2011
Location: Korea, Republic of
Old 06-22-2017 , 13:40   Communicating with socket.io using sourcemod and socket
Reply With Quote #1

Hello, I'm trying to connect to my socket.io server with a plugin using socket(3.0.1)

It works nice when I connected to it with web browser(socket.io client)

But it just close the connection throwing close code 1002 when I connected with my plugin.

Have you guys any idea or solution?

here's my node.js server DEBUG LOG
Code:
Thu, 22 Jun 2017 17:20:03 GMT socket.io:socket joined room H6lgVyeHYXKaNQ7cAAAF
Thu, 22 Jun 2017 17:20:03 GMT engine upgrading existing transport
Thu, 22 Jun 2017 17:20:03 GMT engine:socket might upgrade socket transport from "polling" to "websocket"
Thu, 22 Jun 2017 17:20:03 GMT engine:ws received "Hello"
Thu, 22 Jun 2017 17:20:03 GMT engine:ws closing
Thu, 22 Jun 2017 17:20:13 GMT engine:polling closing
Thu, 22 Jun 2017 17:20:13 GMT engine:polling transport not writable - buffering orderly close
Thu, 22 Jun 2017 17:20:13 GMT socket.io:client client close with reason ping timeout
Thu, 22 Jun 2017 17:20:13 GMT socket.io:socket closing socket - reason ping timeout
And here's my plugins code

PHP Code:
#include <sourcemod>
#include <socket>

char roomId[21];
char yeast[8];

public 
OnPluginStart() {
    new 
Handle:socket SocketCreate(SOCKET_TCPOnSocketError);
    
SocketConnect(socketOnSocketConnectedOnSocketReceiveOnSocketDisconnected"110.45.113.25"3000);
}

public 
OnSocketConnected(Handle:socketany:arg) {
    
// socket is connected, send the http request
    
PrintToServer("######Socket Connected!######");
    
decl String:requestStr[512];
    
    
PrintToServer("######Let's Try to CONNECT to websocket!######");
    
Format(requestStrsizeof(requestStr), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n""getstamp""localhost:3000");
    
SocketSend(socketrequestStr);
    
    
PrintToServer("######Let's Try to HANDSHAKE with websocket!######");    
    
Format(requestStrsizeof(requestStr), "GET /%s%s HTTP/1.1\r\nHost: %s\r\n\r\n""socket.io/?clienttype=SRCDS&EIO=3&transport=polling&t="yeast"localhost:3000");
    
SocketSend(socketrequestStr);
}

public 
OnSocketReceive(Handle:socketString:receiveData[], const dataSizeany:hFile)
{
    
PrintToServer(receiveData);
    if(
StrContains(receiveData"Yeast:"false) != -1)
    {
        
Format(yeast8"%s"receiveData[StrContains(receiveData"Yeast:"true) + 6]);
    }
    else if(
StrContains(receiveData"HTTP/1.1 200 OK"true) != -1)
    {
        
/*
        HTTP/1.1 200 OK
        Content-Type: application/octet-stream
        Content-Length: 101
        Access-Control-Allow-Origin: *
        Set-Cookie: io=iCx7MnGxL1aqNU1gAAAJ; Path=/; HttpOnly
        Date: Mon, 24 Apr 2017 08:03:02 GMT
        Connection: keep-alive
        */
        
decl String:requestStr[512];        
        
PrintToServer("READY TO GO!");
        
        
Format(roomId21"%s"receiveData[StrContains(receiveData"Set-Cookie: io="true) + 15]);
        
// request handshake
        
Format(requestStrsizeof(requestStr), "GET /%s%s HTTP/1.1\r\nHost: %s\r\nConnection: Upgrade\r\nUpgrade: WebSocket\r\nOrigin: http://127.0.0.1:3000/\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: %s\r\n\r\n""socket.io/?clienttype=SRCDS&EIO=3&transport=websocket&sid="roomId"localhost:3000""YW4gc3JjZHMgd3MgdGVzdA==");
        
SocketSend(socketrequestStr);
    }
    else if(
StrContains(receiveData"HTTP/1.1 101 Switching Protocols"true) == 0)
    {
        
/*
        HTTP/1.1 101 Switching Protocols
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Accept: MWRJjQKH/LfNpV4m0z+2rF8En+k=
        Sec-WebSocket-Protocol: chat
        */
        
        
char acceptKey[29];
        
Format(acceptKey29"%s"receiveData[StrContains(receiveData"Sec-WebSocket-Accept: "true) + 22]);
        
PrintToServer("ACCEPT-KEY: %s"acceptKey);

        
char sTemp[11]; // Text, Masked Hello
            
sTemp[0] = 0x81;
            
sTemp[1] = 0x85;
            
sTemp[2] = 0x37;
            
sTemp[3] = 0xfa;
            
sTemp[4] = 0x21;
            
sTemp[5] = 0x3d;
            
sTemp[6] = 0x7f;
            
sTemp[7] = 0x9f;
            
sTemp[8] = 0x4d;
            
sTemp[9] = 0x51;
            
sTemp[10] = 0x58;
        
SocketSend(socketsTemp);                  
    }
    else
    {
        
PrintToServer("You received a data:");
        
PrintToServer(receiveData);
    }

When I send Ping packet to socket.io server, it prints these.

Code:
Thu, 22 Jun 2017 17:22:35 GMT socket.io:socket joined room 2yNY-DX-uNWmtmftAAAG
Thu, 22 Jun 2017 17:22:35 GMT engine upgrading existing transport
Thu, 22 Jun 2017 17:22:35 GMT engine:socket might upgrade socket transport from "polling" to "websocket"
Thu, 22 Jun 2017 17:22:45 GMT engine:socket client did not complete upgrade - closing transport
Thu, 22 Jun 2017 17:22:45 GMT engine:ws closing
Thu, 22 Jun 2017 17:24:00 GMT engine:polling closing
Thu, 22 Jun 2017 17:24:00 GMT engine:polling transport not writable - buffering orderly close
Thu, 22 Jun 2017 17:24:00 GMT socket.io:client client close with reason ping timeout
Thu, 22 Jun 2017 17:24:00 GMT socket.io:socket closing socket - reason ping timeout
__________________
Sorry about my poor English


Last edited by Blowst; 06-29-2017 at 01:00.
Blowst is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 06-22-2017 , 20:22   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #2

WebSockets are not just raw sockets. It's a communications protocol.
Fyren is offline
Kinsi
Senior Member
Join Date: Apr 2013
Old 06-23-2017 , 13:02   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #3

Luckily, somebody already did the hard work of implementing the websocket protocol:

https://forums.alliedmods.net/showthread.php?t=182615
Kinsi is offline
Blowst
Senior Member
Join Date: Feb 2011
Location: Korea, Republic of
Old 06-24-2017 , 01:47   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #4

Quote:
Originally Posted by Kinsi View Post
Luckily, somebody already did the hard work of implementing the websocket protocol:

https://forums.alliedmods.net/showthread.php?t=182615
Yes, I actually checked it out many times. and tried to understand the protocol.

but it implementing only server-side websockets.

It looks more complicated communicating with socket.io server via TCP socket client.

perhaps I'm missing something that need to be at very last step of handshake...
(ping-pong or something?)

thanks for reply
__________________
Sorry about my poor English

Blowst is offline
ElectricStalin
Member
Join Date: Apr 2017
Old 06-24-2017 , 06:33   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #5

Maybe you'd better suited HTTP requests? I make plugin with it, that send data to server, and then recieve response.
ElectricStalin is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 06-24-2017 , 06:38   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #6

Sorry, my reply earlier was way too hasty.

Can you post the handshake headers for the request and response using both your browser and your plugin? I see you have some in your comments, but I'm not sure if that's what you hope to get or what you're actually getting.
Fyren is offline
Blowst
Senior Member
Join Date: Feb 2011
Location: Korea, Republic of
Old 06-24-2017 , 15:25   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #7

Quote:
Originally Posted by Fyren View Post
Sorry, my reply earlier was way too hasty.

Can you post the handshake headers for the request and response using both your browser and your plugin? I see you have some in your comments, but I'm not sure if that's what you hope to get or what you're actually getting.
Now, Server closes the connection after sending any data even after the handshake.
I just want to keep these connected.

OK, first(after socket connection) I send a request for getting session id:
Code:
GET /socket.io/?clienttype=SRCDS&EIO=3&transport=polling&t=LpRVJRD HTTP/1.1
Host: localhost:3000
Then, server response:
Code:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 101
Access-Control-Allow-Origin: *
Set-Cookie: io=q6GVx_8byvJDsuGUAAAA; Path=/; HttpOnly
Date: Sat, 24 Jun 2017 19:03:55 GMT
Connection: keep-alive
I got the session id 'q6GVx_8byvJDsuGUAAAA' now request handshaking:
Code:
GET /socket.io/?clienttype=SRCDS&EIO=3&transport=websocket&sid=q6GVx_8byvJDsuGUAAAA HTTP/1.1
Host: localhost:3000
Connection: Upgrade
Upgrade: WebSocket
Origin: http://127.0.0.1:3000/
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: YW4gc3JjZHMgd3MgdGVzdA==
Then, server switch polling to websocket

Code:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: g0G7yI0fUu+ZAN+kTvfCOjCqOJg=
__________________
Sorry about my poor English

Blowst is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 06-24-2017 , 21:09   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #8

I tested your code using "wscat --listen" for the server and it does seem to work right. Maybe your websocket server is expecting different data to be sent first?

I did make a few small changes, but I don't think anything changed that matters:

PHP Code:
#include <socket>

Handle socket;
public 
OnPluginStart() {
        
socket SocketCreate(SOCKET_TCPOnSocketError);
        
SocketConnect(socketOnSocketConnectedOnSocketReceiveOnSocketDisconnected"127.0.0.1"8000);
        
RegServerCmd("sendhello"sendHello);
}

public 
OnSocketConnected(Handle:sany:arg) {
        
PrintToServer("Socket connected!");
        
sendHandshake();
}

void sendHandshake() {
        
char str[2048];
        
Format(strsizeof(str), "GET / HTTP/1.1\r\nHost: %s\r\nConnection: Upgrade\r\nUpgrade: WebSocket\r\nOrigin: http://127.0.0.1:8000/\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: %s\r\n\r\n""127.0.0.1:8000""YW4gc3JjZHMgd3MgdGVzdA==");
        
PrintToServer("Sending to socket:\n%s"str);
        
SocketSend(socketstr);
}

public 
OnSocketError(Handle sint errorTypeint errorNumany arg) {
        
PrintToServer("Socket error: %d %d"errorTypeerrorNum);
}

public 
OnSocketDisconnected(Handle sany data) {
        
PrintToServer("Socket disconnected.");
}

public 
OnSocketReceive(Handle schar[] receiveDataint szany hFile)
{
        
PrintToServer("Received from socket:\n%s"receiveData);
        if (
StrContains(receiveData"HTTP/1.1 101 Switching Protocols"true) == 0)
        {
                
char acceptKey[29];
                
Format(acceptKey29"%s"receiveData[StrContains(receiveData"Sec-WebSocket-Accept: "true) + 22]);
                
PrintToServer("ACCEPT-KEY: %s"acceptKey);
        }
}

public 
Action sendHello(int args) {
        
PrintToServer("Sending websocket frame");
        
char sTemp[11]; // Text, Masked Hello
        
sTemp[0] = 0x81;
        
sTemp[1] = 0x85;
        
sTemp[2] = 0x37;
        
sTemp[3] = 0xfa;
        
sTemp[4] = 0x21;
        
sTemp[5] = 0x3d;
        
sTemp[6] = 0x7f;
        
sTemp[7] = 0x9f;
        
sTemp[8] = 0x4d;
        
sTemp[9] = 0x51;
        
sTemp[10] = 0x58;
        
SocketSend(socketsTemp);

srcds console:
Code:
Socket connected!
Sending to socket:
GET / HTTP/1.1
Host: 127.0.0.1:8000
Connection: Upgrade
Upgrade: WebSocket
Origin: http://127.0.0.1:8000/
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: YW4gc3JjZHMgd3MgdGVzdA==


Received from socket:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: g0G7yI0fUu+ZAN+kTvfCOjCqOJg=


ACCEPT-KEY: g0G7yI0fUu+ZAN+kTvfCOjCqOJg=
sendhello
Sending websocket frame
Received from socket:
response
wscat:
Code:
$ wscat --listen 8000
listening on port 8000 (press CTRL+C to quit)
client connected
< Hello
> response
>
Fyren is offline
Blowst
Senior Member
Join Date: Feb 2011
Location: Korea, Republic of
Old 06-25-2017 , 02:13   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #9

Quote:
Originally Posted by Fyren View Post
I tested your code using "wscat --listen" for the server and it does seem to work right. Maybe your websocket server is expecting different data to be sent first?

I did make a few small changes, but I don't think anything changed that matters:
I got this. setting sid parameter in handshake request was the problem


Code:
GET /socket.io/?EIO=3&transport=websocket&sid=q6GVx_8byvJDsuGUAAAA HTTP/1.1
Host: 127.0.0.1:8000
Connection: Upgrade
Upgrade: WebSocket
Origin: http://127.0.0.1:8000/
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: YW4gc3JjZHMgd3MgdGVzdA==
working request:
Code:
GET /socket.io/?EIO=3&transport=websocket HTTP/1.1
Host: 127.0.0.1:8000
Connection: Upgrade
Upgrade: WebSocket
Origin: http://127.0.0.1:8000/
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: YW4gc3JjZHMgd3MgdGVzdA==

server console outputs:
Code:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 101
Access-Control-Allow-Origin: *
Set-Cookie: io=koZVmcSaYqjz_Yn5AAAF; Path=/; HttpOnly
Date: Sun, 25 Jun 2017 06:04:51 GMT
Connection: keep-alive


Room(Session) ID: koZVmcSaYqjz_Yn5AAAF
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: g0G7yI0fUu+ZAN+kTvfCOjCqOJg=


ACCEPT-KEY: g0G7yI0fUu+ZAN+kTvfCOjCqOJg=
갫0{"sid":"2_Q9DdgHvOzEwalvAAAG","upgrades":[],"pingInterval":25000,"pingTimeout":60000}
?40

sendhello
Sending websocket frame
42["sendchat", "Hello, Socket.io!"]

You received a data:
?42["updatechat",null,"Hello, Socket.io!"]
web outputs:



Thank you guys for helping to solve the problem
Attached Thumbnails
Click image for larger version

Name:	socket.png
Views:	1272
Size:	17.7 KB
ID:	163721  
__________________
Sorry about my poor English


Last edited by Blowst; 06-25-2017 at 02:18.
Blowst is offline
Kinsi
Senior Member
Join Date: Apr 2013
Old 06-25-2017 , 15:43   Re: Communicating with socket.io using sourcemod and socket
Reply With Quote #10

Do you necessarily need socket.io? Possibly try using raw websockets? Implementing stuff like socket.io's rooms etc would be way too complicated anyways. Possibly give raw websockets a try, or if you want some kind of abstraction which is closer to native primus.io: https://github.com/primus/primus
Kinsi 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 19:03.


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