【问题标题】:Golang websocket handlerGolang websocket 处理程序
【发布时间】:2016-04-10 05:48:35
【问题描述】:

在用 Node.js 编写了很长时间后,我开始学习 Golang,我有点好奇如何实现处理程序 - 我选择使用 Gorilla Websocket,因为我知道它是最可靠的软件包。

例如,在 socket.io 中,您有一个简单的 socket.on 函数,它允许我根据 JSON 中传递的“名称”参数调用函数。

Gorilla websocket 没有实现这样的东西,所以我的问题是我是否要实现 socket.io 背后的逻辑以实现我想要的?

就像根据 websocket 中传输的值做一定的程序一样?

如果是这样 - 我需要自己分别实现客户端(我在前端使用 AngularJS)和服务器端 - 根据我在 AngularJS 中的 JSON 中获得的值创建一个 switch case 语句前端和后端,还有 - 这是最有效的方式吗?

谢谢!

【问题讨论】:

    标签: javascript angularjs go websocket socket.io


    【解决方案1】:

    如果您已经使用 Javascript 一段时间了,那么实现自己的 socket.onsocket.emit 版本真的很容易,这是我为自己的项目制作的版本,但如果需要,您可以拥有它,

    // e.g.
    // let socket = new Socket("ws://w/e");
    // socket.on('connected', () => { console.log('Connected'); });
    // socket.emit('lobby join', { data: { username: 'Boo' } });
    
    // Using ES2015 with Babel
    import {EventEmitter} from 'events';
    
    class Socket {
        constructor(wsurl, ee = new EventEmitter()) {
            let ws = new WebSocket(wsurl);
            this.ee = ee;
            this.ws = ws;
            ws.onmessage = this.message.bind(this);
            ws.onopen = this.open.bind(this);
            ws.onclose = this.close.bind(this);
        }
        on(name, fn) {
            this.ee.on(name, fn);
        }
        off(name, fn) {
            this.ee.removeListener(name, fn);
        }
        emit(name, data) {
            const message = JSON.stringify({name, data});
            this.ws.send(message);
        }
        message(e) {
            try {
                const msgData = JSON.parse(e.data);
                this.ee.emit(msgData.name, msgData.data);
            }
            catch(err) {
                let error = {
                    message: err
                }
                console.log(err)
                this.ee.emit(error.message)
            }
        }
        open() {
            this.ee.emit('connected');
        }
        close() {
            this.ee.emit('disconnected');
        }   
    }
    
    export default Socket
    

    这将让你使用你常用的socket.on('event', fn); 和其他什么

    至于在服务器端处理:

    为了接收消息,我个人只是做一个 switch 语句,将传入的字符串匹配到一个函数,例如:

    // readPump pumps messages from the websocket connection to the hub.
    func (c *connection) readPump() {
        defer c.ws.Close()
        for {
            _, message, err := c.ws.ReadMessage()
            if err != nil {
                break
            }
            var incMessage interface{}
            err = json.Unmarshal(message, &incMessage)
            if err != nil {
                log.Println(err)
            }
            incMessageMap := incMessage.(map[string]interface{})
            switch incMessageMap["name"] {
            case "lobby join":
                 // Do something to handle joining
            case "lobby leave":
                 // Do something to handle leaving
            }
        }
    }
    

    为了发送它们,我的连接上有一个send channel,它存储在地图中,当我需要发出时,我有一个简单的结构,它带有消息名称和数据,例如:

    type wsMsg struct {
        Name string                 `json:"name"`
        Data map[string]interface{} `json:"data"`
    }
    
    
    c.send <- wsMsg{
         "user joined",
         map[string]interface{}{
              "username": "Booh",
         },
    }
    

    然后在客户端它会来

    socket.on('user joined', (msg) => {
        console.log(msg) // { username: "Booh" }
    });
    

    我建议查看 gorillas git 上的示例:https://github.com/gorilla/websocket/tree/master/examples/chat

    【讨论】:

    • 太棒了!这也是 Go 中最有效的方法还是只是一个简单的解决方案?
    • @Random 我只用了几个月的 Go,所以在效率方面我不确定,但我从来没有遇到过这种方法的问题,而且似乎没有以任何方式变慢。我的实现平均大约有 5-10k 个并发连接,而​​且它从不打嗝
    • 这很复杂而且很烦人。为什么不用googollee/go-socket.io 为什么gorilla/websocket里面的star比较多-.-
    【解决方案2】:

    这是一个使用 golang websocket 流式传输视频的工作示例 https://github.com/interviewparrot/OpenAVStream

    让我知道它是否足够好

    【讨论】:

    • 在回答一个老问题时,如果您包含一些上下文来解释您的答案如何提供帮助,那么您的答案将对其他 StackOverflow 用户更有用,特别是对于已经有一个已接受答案的问题。请参阅:How do I write a good answer
    猜你喜欢
    • 2022-10-07
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    相关资源
    最近更新 更多