golang中的一对一聊天

时间:2017-11-14 07:40:40

标签: go websocket socket.io chat

我想在revel框架中创建一对一的聊天,但它会出错。首先根据演示在狂欢聊天中工作,但刷新页面不起作用,所以我尝试了这种方法,不知道如何处理单个聊天。

这是一个错误:

app server.go:2848: http: panic serving 127.0.0.1:50420: interface conversion: interface is nil, not io.Writer goroutine 166 [running]: net/http.(*conn).serve.func1(0xc4201d03c0)

我的go代码是我处理ws root的地方,单个用户聊天需要db连接。我正在使用posgres

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var clients = make(map[*websocket.Conn]bool) // connected clients
var broadcast = make(chan Message)           // broadcast channel

// Configure the upgrader
var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

// Define our message object
type Message struct {
    Email    string `json:"email"`
    Username string `json:"username"`
    Message  string `json:"message"`
    Created  string `json:"created"`
}

func main() {
    // Create a simple file server
    fs := http.FileServer(http.Dir("public"))
    http.Handle("/", fs)

    // Configure websocket route
    http.HandleFunc("/ws", handleConnections)

    // Start listening for incoming chat messages
    go handleMessages()

    // Start the server on localhost port 8000 and log any errors
    log.Println("http server started on :8090")
    err := http.ListenAndServe(":8090", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // Upgrade initial GET request to a websocket
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    // Make sure we close the connection when the function returns
    defer ws.Close()

    // Register our new client
    clients[ws] = true

    for {
        var msg Message
        // Read in a new message as JSON and map it to a Message object
        err := ws.ReadJSON(&msg)
        if err != nil {
            log.Printf("error: %v", err)
            delete(clients, ws)
            break
        }
        // Send the newly received message to the broadcast channel
        broadcast <- msg
    }
}

func handleMessages() {
    for {
        // Grab the next message from the broadcast channel
        msg := <-broadcast
        // Send it out to every client that is currently connected
        for client := range clients {
            err := client.WriteJSON(msg)
            if err != nil {
                log.Printf("error: %v", err)
                client.Close()
                delete(clients, client)
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为您错误地使用了gorilla/websocket API。您复制了echo示例,作为基本演示,它只能处理单个ws连接。从chat示例开始。特别要注意serveWs阻挡时handleConnections是非阻塞呼叫的事实,即它永远不会返回。在这里查看gorilla/websocket API使用的全功能示例: https://github.com/tinode/chat/blob/master/server/wshandler.go

正如Cerise L正确指出的那样,你肯定会在clients上进行比赛,尽管我认为它不太可能引起恐慌。我认为最可能的恐慌源是在一个封闭的http连接上调用Upgrade。由于你没有公布恐慌的全部输出,所以不可能完全说出来。