#go #websocket
#Вперед #websocket
Вопрос:
Задача проста: установить соединение и отправить сообщение пользователю
После прочтения в Интернете получается что-то вроде этого
Подключение
func echo(w http.ResponseWriter, r *http.Request) {
con, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
defer con.Close()
for {
mt, message, err := con.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", message)
err = con.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
}
}
func main() {
flag.Parse()
log.SetFlags(0)
http.HandleFunc("/echo", echo)
}
Отправка сообщения из метода
jsonData, _ := json.Marshal(data)
users := make(map[string]*websocket.Conn)
_ = users[uid].WriteJSON(jsonData)
Как вы можете себе представить, это не работает, и я нахожусь в каком-то ступоре.
Не могли бы вы сказать мне, действительно ли я действую в правильном направлении?
Я уверен, что кто-то уже сделал эту очень простую настройку, пожалуйста, ответьте =)
Комментарии:
1. Общий подход к использованию карты с ключом uid хорош. Есть несколько проблем с кодом в вопросе: (1) Приложение дважды кодируется
data
как JSON. Закодируйте его один раз с помощью_ = users[uid].WriteJSON(data)
. (2) Выражениеusers[uid]
вычисляется с нулевым указателем, поскольку карта создается в предыдущей строке. Создайте карту один раз. Защитил его с помощью мьютекса. (3) Всегда проверяйте ошибки. Возвращаемое значение из WriteJSON игнорируется.
Ответ №1:
попробуйте следующий код ниже, задавайте вопросы, если вы заблудились.
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/rs/cors"
)
var router = mux.NewRouter().StrictSlash(true)
var upgrader = websocket.Upgrader{
ReadBufferSize: 0,
WriteBufferSize: 0,
}
type tester struct {
Results int `json:"Results"`
ID int `json:"ID"`
User string `json:"User"`
}
var testers tester
var list = ""
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home Page")
}
func reader(conn *websocket.Conn) {
for {
//read in a message
messageType, p, err := conn.ReadMessage()
if err != nil {
fmt.Println(err)
return
}
//printing out the message in the server for clarity
fmt.Println(string(p))
list = string(p)
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func wsEndpoint(w http.ResponseWriter, r *http.Request) {
//This will determine whether or not an incoming request from
// a different domain is allowed to connect, and if it isn’t they’ll be hit with a CORS error.
upgrader.CheckOrigin = func(r *http.Request) bool { return true }
//upgrade this connection to a webSocket connection
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
} else {
// helpful log statement to show connections
log.Println("Client Connected")
for {
//read in a message
_, p, err := ws.ReadMessage()
if err != nil {
fmt.Println(err)
return
}
//printing out the message in the server for clarity
list = string(p)
fmt.Println(list)
}
}
}
// define a reader which will listen for
// new messages being sent to our WebSocket
// endpoint
func setupRoutes() {
router.HandleFunc("/", homePage)
router.HandleFunc("/ws", wsEndpoint)
}
func main() {
setupRoutes()
handler := cors.AllowAll().Handler(router)
log.Fatal(http.ListenAndServe(":8080", handler))
}