Обслуживание веб-узла в Go
Я начинаю поиграть с websockets + пойти и хорошо. Думаю, я неправильно понимаю что-то общее с websockets в Go.
Я бы хотел просто прослушать подключение к веб-сокету и обработать его соответствующим образом. Однако все примеры, которые я вижу в Go, используя websocket, служат веб-странице, которая затем подключается к websocket, это требование?
Ниже приведен базовый эхо-сервер, который у меня установлен:
package main
import (
"fmt"
"code.google.com/p/go.net/websocket"
"net/http"
)
func webHandler(ws *websocket.Conn) {
var s string
fmt.Fscan(ws, &s)
fmt.Println("Received: ", s)
}
func main() {
fmt.Println("Starting websock server: ")
http.Handle("/echo", websocket.Handler(webHandler))
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
Это javascript, используемый для подключения:
ws = new WebSocket("ws://localhost:8080/echo");
ws.onmessage = function(e) {
console.log("websock: " + e.data);
};
Однако это приводит к: Соединение WebSocket с 'ws://localhost: 8080/echo' не выполнено: Неожиданный код ответа: 403
Ответы
Ответ 1
При работе с веб-сайтами из Javascript вам редко приходится читать фреймы напрямую. Честно говоря, я даже не знаю, как это сделать.
К счастью, пакет websocket уже имеет тип Codec
, который делает это для вас. Мое предложение состоит в том, чтобы использовать предопределенный код websocket.Message вместо Recieve
и Send
.
Сообщение представляет собой кодек для отправки/получения текстовых/двоичных данных в фрейме в соединении с WebSocket. Для отправки/получения текстового фрейма используйте тип строки. Чтобы отправить/получить двоичный фрейм, используйте [] тип байта.
Используя websocket.Message, ваш webHandler будет выглядеть примерно так:
func webHandler(ws *websocket.Conn) {
var in []byte
if err := websocket.Message.Receive(ws, &in); err != nil {
return
}
fmt.Printf("Received: %s\n", string(in))
websocket.Message.Send(ws, in)
}
И нет, это не требование, чтобы Go обслуживал веб-страницу. Полученная ошибка 403 не связана с Go или пакетом websocket.
Ответ 2
У меня была аналогичная проблема, и проблема с ошибкой 403 связана с тем, как Go рассматривает заголовок http Origin:
Обработчик - это простой интерфейс для клиента браузера WebSocket. Он проверяет, является ли заголовок Origin действительным URL по умолчанию. Возможно, вы захотите проверить websocket.Conn.Config(). Начало в func. Если вы используете сервер вместо обработчика, вы можете вызвать websocket.Origin и проверить происхождение в вашей функции Handshake. Итак, если вы хотите принять не-браузерный клиент, который не отправляет заголовок Origin, вы можете использовать Server. который не проверяет происхождение в своем рукопожатии.
Чтобы отключить проверку Origin, вы должны использовать что-то вроде:
http.HandleFunc("/echo",
func (w http.ResponseWriter, req *http.Request) {
s := websocket.Server{Handler: websocket.Handler(webHandler)}
s.ServeHTTP(w, req)
});
По крайней мере, это решило проблему для меня (связь между сервером и сервером WebSocket), и я думаю, что она также может решить проблему, если заголовок источника не совпадает.