I have two processes running, written in Go in which one (sender.go) sends a message to another (listener.go) while being stuck in a for loop via websockets.
The issue is that listener.go only realizes it received the message after it terminates the loop.
I have tried several websocket libraries, I even tried using regular tcp streams, but it won't work when compiled in webassembly because browser won't support it. The syscall/js websocket seemed to be the perfect fit despite this behaviour.
here's listener.go
func registerCallbacks(ws js.Value) {
ws.Call("addEventListener", "message", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
message := args[0].Get("data").String()
fmt.Println("message received ")
fmt.Println(message)
return nil
}))
}
func main() {
c := make(chan struct{}, 0)
toIP := "127.0.0.1"
toPort := 8081
ws := js.Global().Get("WebSocket").New(fmt.Sprintf("ws://%s:%d/ws", toIP, toPort))
registerCallbacks(ws)
const bigNum uint64 = 100000 * 10000
cb := func(this js.Value, args []js.Value) interface{} {
for i := uint64(0); i < bigNum; i++ {
doThings()
if i%10000000 == 0 {
fmt.Println("skimmed ten millions ")
}
}
fmt.Println("Exited for loop !!")
return nil
}
// call cb() in script of index.html from a button
js.Global().Set("cb", js.FuncOf(cb))
<-c
}
So is sender.go,
func main() {
toIP := "127.0.0.1"
toPort := 8081
ws := js.Global().Get("WebSocket").New(fmt.Sprintf("ws://%s:%d/ws", toIP, toPort))
time.Sleep(1 * time.Second)
fmt.Println("sending ")
ws.Call("send", js.ValueOf("msg"))
fmt.Println("Program exit ")
}
If someone's willing to reproduce the issue here's the websocket server which receives message from sender to forward it to receiver, written in node.js, just copy and paste this, it works fine with several projects
const port = 8081;
const host = '127.0.0.1';
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {});
server.listen(port, host, () => {
console.log('WS Server is running on port ' + port + '.');
});
wsServer = new WebSocketServer({
httpServer: server
});
let sockets = [];
wsServer.on('request', function(request) {
var connection = request.accept(null, request.origin);
sockets.push(connection)
console.log("Connection with node initiated")
connection.on('message', function(message) {
console.log("message received "+message)
sockets.forEach(function(s, index, array) {
if (message.type === 'utf8') {
broadcastData = message.utf8Data
console.log("message is: "+ broadcastData)
if(s!= connection) {
console.log('send data to ' + s.socket.remotePort + ': ' + broadcastData);
s.sendUTF(broadcastData)
}
}
});
});
});
I am expecting listener.go to receive message before it exits the for loop
PS: Using sleep statement is not a good help , because when this for loop runs inside a js callback, the sleep statement outputs a panic.