dongre6073 2016-01-06 07:46
浏览 130
已采纳

Golang WebSocket处理程序

I've started learning Golang after writing in Node.js for a long time and I'm a bit curious as to how am I to implement a handler - I've opted to use Gorilla Websocket since I understood it's the most reliable package out there.

In socket.io for example you have the simple socket.on function that allows me to call a function based on the "name" parameter passed in JSON.

Gorilla websocket doesn't implement such a thing, so my question is am I to sort of implement the logic behind socket.io in order to achieve what I want ?

As in do a certain procedure based on the value transferred in the websocket ?

If so - I need to implement it both client (I'm using AngularJS on the front-end) and server side separately by my own - make a switch case statement based on a value I get in JSON both in AngularJS for the front-end and in Go for the back-end, and also - is that the most efficient way ?

Thanks !

  • 写回答

1条回答 默认 最新

  • dongwei1954 2016-01-06 08:09
    关注

    If you've been using Javascript for a while it is really easy to implement your own version of socket.on and socket.emit here is one I made for my own projects but you can have it if you need,

    // 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
    

    This will let you use your common socket.on('event', fn); and what not

    As for handling it on the servers end:

    For receiving messages, I personally just make a switch statement that will match an incoming string to a function, e.g.:

    // 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
            }
        }
    }
    

    For sending them I have a send channel on my connections that is stored in a map and when I need to emit I have a simple struct that takes a message name, and data, e.g.:

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

    Then on the client side it would come as

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

    I suggest looking at the examples on gorillas git: https://github.com/gorilla/websocket/tree/master/examples/chat

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 maixpy训练模型,模型训练好了以后,开发板通电会报错,不知道是什么问题
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容