Go websockets eof

I am trying to make a simple command forwarder to connect my home computer to my own server so that I can push commands to my server and my home computer will receive it. These commands are simple pause / resume for my bootloader. My design is that on the server I run an instance of the hub, which creates a window for sending commands and a window for the backend for transferring these commands to my computer. I limit these two β€œwindows” to the channel, they start the server. When the client connects and sends a message to the hub, it is transmitted through the channel to the backend window, and then to the real backend (on my home PC). When the backend responds to the backend window on the hub, the hub returns the result to the client.

With this approach, only the first message passes and works with my bootloader. I have to reconnect the backend from my home computer with the hub every time I receive a message to make it work correctly. I don't think the right way is with websockets, so I'm here. After one successful request (when the backend completes and responds to the result), it forever loops with an EOF error.

Important parts of the code are:

If you put the source code in your GOPATH (I am developing it for the version hint for supporting modern websites) to compile it: go build gosab/cmd to run it:

  • ./cmd -mode="hub" hub
  • ./cmd -mode="backend" --address="localhost:8082" backend

To pass messages to a hub, use this javascript:

 var s = new WebSocket("ws://localhost:8082") s.send("1 5") 

So how do I deal with this? Are channels a good way to communicate between two different requests?

+6
source share
1 answer

I am surprised that you did not receive an answer to this question.

What you need to do is something like the code below. When you receive an incoming connection to the network, a new goroutine is created for this connection. If you release this goroutine, it will disconnect the websocket client.

I make the assumption that you will not necessarily run the client and server on the same computer. If you always do this, then it would be better to do intercom via channels or such, instead of using web ports or a network port. I only mention this because I'm not quite sure what you are using it for. I just hope I answered the right part of your question.

 package main import ( "code.google.com/p/go.net/websocket" "flag" "fmt" "net/http" "os" "time" ) type Message struct { RequestID int Command string SomeOtherThing string Success bool } var mode *string = flag.String("mode", "<nil>", "Mode: server or client") var address *string = flag.String("address", "localhost:8080", "Bind address:port") func main() { flag.Parse() switch *mode { case "server": RunServer() case "client": RunClient() default: flag.Usage() } } func RunServer() { http.Handle("/", http.FileServer(http.Dir("www"))) http.Handle("/server", websocket.Handler(WSHandler)) fmt.Println("Starting Server") err := http.ListenAndServe(*address, nil) if err != nil { fmt.Printf("HTTP failed: %s\n", err.Error()) os.Exit(1) } } func WSHandler(ws *websocket.Conn) { defer ws.Close() fmt.Println("Client Connected") for { var message Message err := websocket.JSON.Receive(ws, &message) if err != nil { fmt.Printf("Error: %s\n", err.Error()) return } fmt.Println(message) // do something useful here... response := new(Message) response.RequestID = message.RequestID response.Success = true response.SomeOtherThing = "The hot dog left the castle as requested." err = websocket.JSON.Send(ws, response) if err != nil { fmt.Printf("Send failed: %s\n", err.Error()) os.Exit(1) } } } func RunClient() { fmt.Println("Starting Client") ws, err := websocket.Dial(fmt.Sprintf("ws://%s/server", *address), "", fmt.Sprintf("http://%s/", *address)) if err != nil { fmt.Printf("Dial failed: %s\n", err.Error()) os.Exit(1) } incomingMessages := make(chan Message) go readClientMessages(ws, incomingMessages) i := 0 for { select { case <-time.After(time.Duration(2e9)): i++ response := new(Message) response.RequestID = i response.Command = "Eject the hot dog." err = websocket.JSON.Send(ws, response) if err != nil { fmt.Printf("Send failed: %s\n", err.Error()) os.Exit(1) } case message := <-incomingMessages: fmt.Println(message) } } } func readClientMessages(ws *websocket.Conn, incomingMessages chan Message) { for { var message Message err := websocket.JSON.Receive(ws, &message) if err != nil { fmt.Printf("Error: %s\n", err.Error()) return } incomingMessages <- message } } 
+7
source

Source: https://habr.com/ru/post/908655/


All Articles