rooms - El cliente socket.io usa Go
socket.io express (2)
Comenzando con un ejemplo de socket.io
funcionamiento (back-end: Python / Flask, front-end: socket.io.js v2.0.3), ahora trato de configurar un cliente con Go pero ni siquiera puedo pasar la fase de handshake . Disculpas por la publicación larga ... (Al final también se ha agregado un cliente de Python que hace lo que quiero implementar en Go)
(El siguiente trabajo):
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)
Interfaz:
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);
Herramientas de desarrollador: veo algunas solicitudes hasta que el navegador y el servidor seleccionan usar websockets y marcos de intercambio:
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
Registros del servidor:
"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
Mi intento con Go, (no funciona):
El código proviene de este ejemplo de cliente en 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)
}
Ir código de salida:
Connected
Registros del servidor:
"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 200 0 1.004291
¿Hay algo que me estoy perdiendo? Con el código Go no veo ningún sid
, transport=polling
... Además, solo hay unas pocas preguntas etiquetadas con [go] [socket.io]
, lo que me hace pensar que he elegido la ruta incorrecta. Estaría agradecido por cualquier pensamiento, ideas sobre esto.
@ John Weldon
Tu código produce lo siguiente:
Cliente:
$ 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
Servidor:
(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
Observe que el servidor funciona on.(''connect''...)
y on.(''join'',...)
no produjo registros.
Cliente de Python (funciona):
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'')
registros del cliente:
python3 test.py
[Connected]
[Disconnected]
[Disconnected]
registros del servidor:
(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
Creo que lo estás haciendo bien, excepto que olvidó enviar el mensaje de join
, tal vez algo así como:
package main
import (
"log"
"runtime"
"sync"
"time"
"github.com/graarh/golang-socketio"
"github.com/graarh/golang-socketio/transport"
)
func doSomethingWith(c *gosocketio.Client, wg *sync.WaitGroup) {
if res, err := c.Ack("join", "This is a client", time.Second*3); err != nil {
log.Printf("error: %v", err)
} else {
log.Printf("result %q", res)
}
wg.Done()
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
c, err := gosocketio.Dial(
gosocketio.GetUrl("127.0.0.1", 3003, 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)
}
wg := &sync.WaitGroup{}
wg.Add(1)
go doSomethingWith(c, wg)
wg.Wait()
log.Printf("Done")
}
Observe la llamada de goroutine a la función que realmente comunica el mensaje ''join'' al servidor.
Además, observe el uso de un sync.WaitGroup
para bloquear hasta que complete la rutina, en lugar de usar time.Sleep()
para esperar.
De acuerdo con los comentarios anteriores, hemos encontrado que la conexión websocket está funcionando. Creo que el problema está aquí: socket.io
se desarrolló hace muchos años cuando los WebSockets nativos no eran bien compatibles con la mayoría de los navegadores y servidores / proxies / enrutadores intermedios. Por lo tanto, tiene controles y retrocesos especiales para actualizar y degradar una conexión (por ejemplo, para longpolling). Si ya ha instalado la conexión, puede comenzar a trabajar sin intercambios de claves especiales con otro protocolo.
Intente comenzar a usar la conexión y realizar los siguientes pasos en las lógicas del nivel de la aplicación ( Join
etc.). ¿Está funcionando?
Creo que hoy en día, WS es compatible con el 99% de los clientes. Si no quiere perder la oportunidad de que algún cliente no funcione, puede mantener sockets.io
en el proyecto. Pero a veces tendrá que darse cuenta de sus lógicas de conexiones en WS.