为了账号安全,请及时绑定邮箱和手机立即绑定

Golang websocket 处理程序

Golang websocket 处理程序

Go
一只名叫tom的猫 2021-12-06 19:32:22
在使用 Node.js 编写了很长时间后,我开始学习 Golang,我对如何实现处理程序有点好奇——我选择使用 Gorilla Websocket,因为我知道它是最可靠的包那里。例如,在 socket.io 中,您有一个简单的 socket.on 函数,它允许我根据 JSON 中传递的“名称”参数调用函数。Gorilla websocket 没有实现这样的东西,所以我的问题是我是否要实现 socket.io 背后的逻辑以实现我想要的?就像根据 websocket 中传输的值执行某个程序一样?如果是这样 - 我需要在客户端(我在前端使用 AngularJS)和服务器端分别实现它 - 根据我在 AngularJS 中在 JSON 中获得的值创建一个 switch case 语句作为前端 - end 和 in Go 作为后端,还有 - 这是最有效的方式吗?
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

如果您已经使用 Javascript 一段时间了,那么实现您自己的 Javascript 版本真的很容易socket.on,socket.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


查看完整回答
反对 回复 2021-12-06
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

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

让我知道它是否足够好


查看完整回答
反对 回复 2021-12-06
  • 2 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信