How to create a WebSocket server that any client from any domain-name/ip-address can communicate with. I don't want to have to open a page with a custom address provided by the server in order to communicate with the server.
The goal is to be able to communicate with the WebSocket server, through browser extensions, for example, or through any unexpected endpoint.
server.go
package main
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err) // no error just when websocket connecte from my domain
}
for {
// Read message from browser
msgType, msg, _ := conn.ReadMessage()
// Print the message to the console
fmt.Printf("%s sent: %s\n", conn.RemoteAddr(), string(msg))
// Write message back to browser
if err = conn.WriteMessage(msgType, msg); err != nil {
return
}
}
})
http.HandleFunc("/client", func(w http.ResponseWriter, r *http.Request) { // I dont need this
http.ServeFile(w, r, "client.html")
})
http.ListenAndServe(":8080", nil)
}
client.js
<!DOCTYPE html>
<html>
<head>
<meta charset=utf8>
<meta name=viewoirt content="width=device-width, initial-scale=1.0">
<title>click bot</title>
</head>
<body>
<input id="input" type="text" />
<button onclick="send()">Send</button>
<pre id="output"></pre>
<script>
var input = document.getElementById("input");
var output = document.getElementById("output");
var socket = new WebSocket("ws://localhost:8080/");
socket.onopen = function () {
output.innerHTML += "Status: Connected\n";
};
socket.onmessage = function (e) {
output.innerHTML += "Server: " + e.data + "\n";
};
function send() {
socket.send(input.value);
input.value = "";
}
</script>
</body>
</html>
Everything is fine when I connecte through localhost:8080/client
Either via the link or by injecting it through browser extensions.
But when I inject it into another page that doesn't have the same ip address, it doesn't work. For example: For example, when I am typing in the console: websocket = new webSocket('ws://localhost: 8080')
in a domain other than my domain.
CLIEnt ERRORE :
VM447:1 WebSocket connection to 'ws://localhost:8080/' failed: Connection closed before receiving a handshake response.
SERVER ERROR : websocket: request origin not allowed by Upgrader.CheckOrigin
For example, when I am typing in the console: websocket = new webSocket('ws://localhost: 8080') in a domain other than my domain.
The server code in the question implements a same-origin policy. Change the check origin function to allow connections from any origin:
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool { return true }
}
The question says that the server code ignores the error from upgrade for simplicity. If the server code had logged the error, the problem would have been immediately obvious. Always handle errors!
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return
}