Starting with a working socket.io
example (back-end: Python/Flask, front-end: socket.io.js v2.0.3), I now try to set up a client with Go but can't even pass the handshake phase. Apologies for the long post... (At the end I have also added a Python client which does what I want to implement in Go)
(The following work):
back-end:
@socketio.on('connect', namespace='/endpoint')
def connect():
print("Client connected with request sid "+request.sid)
@socketio.on('join', namespace='/endpoint')
def join(message):
print("Server received from client:" +message)
print("Client just joined room with request sid "+request.sid)
join_room(request.sid)
front-end:
namespace = '/endpoint';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
var client_join_message = "This is a client";
socket.emit('join', client_join_message);
Developer tools: I notice a few requests until the browser and the server select to use websockets and exchange frames:
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=LxcgetJ
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetf&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgeti&sid=025e105a5093467d994a891367380aa3
ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetw&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetx&sid=025e105a5093467d994a891367380aa3
Server logs:
"GET /socket.io/?EIO=3&transport=polling&t=LxcgetJ HTTP/1.1" 200 381 0.000322
Client connected with request sid 025e105a5093467d994a891367380aa3
"POST /socket.io/?EIO=3&transport=polling&t=Lxcgetf&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 219 0.000806
(6450) accepted ('127.0.0.1', 45034)
"GET /socket.io/?EIO=3&transport=polling&t=Lxcgeti&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 227 0.003941
"POST /socket.io/?EIO=3&transport=polling&t=Lxcgetw&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 219 0.001650
"GET /socket.io/?EIO=3&transport=polling&t=Lxcgetx&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 215 0.000235
Server received from client:This is a client
Client just joined room with request sid 025e105a5093467d994a891367380aa3
My try with Go, (doesn't work):
The code comes from this client example in github.com/graarh/golang-socketio:
package main
import (
"github.com/graarh/golang-socketio"
"github.com/graarh/golang-socketio/transport"
"log"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
c, err := gosocketio.Dial(
gosocketio.GetUrl("127.0.0.1", 5000, false),
transport.GetDefaultWebsocketTransport())
if err != nil {
log.Fatal(err)
}
err = c.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) {
log.Fatal("Disconnected")
})
if err != nil {
log.Fatal(err)
}
err = c.On(gosocketio.OnConnection, func(h *gosocketio.Channel) {
log.Println("Connected")
})
if err != nil {
log.Fatal(err)
}
time.Sleep(1 * time.Second)
}
Go code output:
Connected
Server logs:
"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 200 0 1.004291
Is there anything that I'm missing? With the Go code I don't see any sid
, transport=polling
... Also, there are only a few questions tagged with [go] [socket.io]
, which makes me think I've chosen the wrong path... I would be grateful for any thoughts, ideas on this.
@John Weldon
Your code produces the following:
Client:
$ go run gotest5.go
2017/10/11 11:21:40 Connected
2017/10/11 11:21:40 result ""
2017/10/11 11:21:40 Done
Server:
(4380) wsgi starting up on http://127.0.0.1:5000
(4380) accepted ('127.0.0.1', 38860)
127.0.0.1 - - [11/Oct/2017 11:21:40] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 200 0 0.003100
Notice that the server functions on.('connect'...)
and on.('join',...)
didn't produce logs.
Python client (it works):
from socketIO_client import SocketIO, BaseNamespace
class ThisNamespace(BaseNamespace):
def on_connect(self):
print('[Connected]')
def on_reconnect(self):
print('[Reconnected]')
def on_disconnect(self):
print('[Disconnected]')
with SocketIO('127.0.0.1', 5000, ThisNamespace) as socketIO:
this_namespace = socketIO.define(ThisNamespace, '/endpoint')
client logs:
python3 test.py
[Connected]
[Disconnected]
[Disconnected]
server logs:
(6047) wsgi starting up on http://127.0.0.1:5000
(6047) accepted ('127.0.0.1', 38900)
127.0.0.1 - - [11/Oct/2017 11:53:27] "GET /socket.io/?t=1507712007314-0&transport=polling&EIO=3 HTTP/1.1" 200 381 0.000859
(6047) accepted ('127.0.0.1', 38902)
Client connected with request sid 919ed69264dd4e9f93e7af0294970dbd
Client disconnected with request.sid 919ed69264dd4e9f93e7af0294970dbd
127.0.0.1 - - [11/Oct/2017 11:53:27] "GET /socket.io/?sid=919ed69264dd4e9f93e7af0294970dbd&transport=websocket&EIO=3 HTTP/1.1" 200 0 0.032171
According to commentws above, we've found websocket connection itself is working. I think problem is here -
socket.io
was developed many years ago when native WebSockets were not well supported by majority of browsers and inermediate servers/proxies/routers. So it has a special checks and fallbacks when to upgrade and downgrade a connection (to longpolling for example). If you have already installed connection you may start working without special key exchanges with another protocol.Try to start using connection and performing next steps at application level logics (
Join
and so on). Is it working?I think nowadays WS are supported well for 99% of clients. If you want not to loose chance some client will be not working you may keep
sockets.io
in project. But sometimes you'll have to realize its connections logics in WS.I think you're doing it right except you forgot to actually send the
join
message, maybe something like:Notice the goroutine call to the function that actually communicates the 'join' message to the server.
Also, notice the use of a
sync.WaitGroup
to block until the goroutine completes, instead of usingtime.Sleep()
to wait.