AI编程助手
AI免费问答

Go如何使用websocket实现弹幕功能

藏色散人   2020-08-20 13:08   3913浏览 转载

下面由Golang教程栏目给大家Go使用websocket实现弹幕功能的方法,希望对需要的朋友有所帮助!

使用websocket协议,客户端发送一个消息,服务端广播到所有有效连接中。
主要思路:
1.封装*websocket.conn,用client结构表示一个客户端。
2.维持一个map[client]bool,表示有效的客户端映射,用于广播消息
3.除了处理websocket连接外,还要开启一个广播协程,监听客户端连接,断开,发弹幕事件。

推荐:《go语言教程

主要的结构:

type Client struct{
    wsConnect *websocket.Conn
    inChan chan []byte
    outChan chan []byte
    closeChan chan byte
    Name string //客户的名称
    Id string //客户id,唯一
    mutex sync.Mutex  // 对closeChan关闭上锁
    IsClosed bool  // 防止closeChan被关闭多次
}
type Message struct {
    EventType byte  `json:"type"`       // 0表示用户发布消息;1表示用户进入;2表示用户退出
    Name string     `json:"name"`       // 用户名称
    Message string  `json:"message"`    // 消息内容
}
    clients = make(map [*util.Client] bool)      // 用户组映射
    join = make(chan *util.Client, 10)        // 用户加入通道
    leave = make(chan *util.Client, 10)       // 用户退出通道
    message = make(chan Message, 10)    // 消息通道

server端代码

package main

import (
    "encoding/json"
    "fmt"
    "github.com/gorilla/websocket"
    "goGin/server/util"
    "net/http"
)

var(
    upgrader = websocket.Upgrader{
        // 允许跨域
        CheckOrigin:func(r *http.Request) bool{
            return true
        },
    }
    clients = make(map [*util.Client] bool)      // 用户组映射
    join = make(chan *util.Client, 10)        // 用户加入通道
    leave = make(chan *util.Client, 10)       // 用户退出通道
    message = make(chan Message, 10)    // 消息通道
)
type Message struct {
    EventType byte  `json:"type"`       // 0表示用户发布消息;1表示用户进入;2表示用户退出
    Name string     `json:"name"`       // 用户名称
    Message string  `json:"message"`    // 消息内容
}

func wsHandler(w http.ResponseWriter , r *http.Request){
    var(
        wsConn *websocket.Conn
        err error
        client *util.Client
        data []byte
    )
    r.ParseForm() //返回一个map,并且赋值给r.Form
    name := r.Form["name"][0]
    id := r.Form["id"][0]

    if wsConn , err = upgrader.Upgrade(w,r,nil); err != nil{
        return
    }

    if client , err = util.InitConnection(wsConn); err != nil{
        goto ERR
    }
    client.Id = id
    client.Name = name

    // 如果用户列表中没有该用户
    if !clients[client] {
        join <h3>封装client</h3><pre class="brush:php;toolbar:false">package util
import (
    "github.com/gorilla/websocket"
    "sync"
    "errors"
)
type Client struct{
    wsConnect *websocket.Conn
    inChan chan []byte
    outChan chan []byte
    closeChan chan byte
    Name string //客户的名称
    Id string //客户id,唯一

    mutex sync.Mutex  // 对closeChan关闭上锁
    IsClosed bool  // 防止closeChan被关闭多次
}
func InitConnection(wsConn *websocket.Conn)(conn *Client ,err error){
    conn = &Client{
        wsConnect:wsConn,
        inChan: make(chan []byte,1000),
        outChan: make(chan []byte,1000),
        closeChan: make(chan byte,1),
        IsClosed:false,
    }
    // 启动读协程
    go conn.readLoop();
    // 启动写协程
    go conn.writeLoop();
    return
}
func (conn *Client)ReadMessage()(data []byte , err error){
    select{
    case data = <h3>客户端代码</h3><pre class="brush:php;toolbar:false">nbsp;html>


    <title>go websocket</title>
    <meta><script>
    var wsUri ="ws://127.0.0.1:7777/ws?name=aaa&id=112";
    var output;

    function init() {
        output = document.getElementById("output");
        testWebSocket();
    }

    function testWebSocket() {
        websocket = new WebSocket(wsUri);
        websocket.onopen = function(evt) {
            onOpen(evt)
        };
        websocket.onclose = function(evt) {
            onClose(evt)
        };
        websocket.onmessage = function(evt) {
            onMessage(evt)
        };
        websocket.onerror = function(evt) {
            onError(evt)
        };
    }

    function onOpen(evt) {
        writeToScreen("CONNECTED");
        // doSend("WebSocket rocks");
    }

    function onClose(evt) {
        writeToScreen("DISCONNECTED");
    }

    function onMessage(evt) {
        writeToScreen(&#39;<span style="color: blue;">RESPONSE: &#39;+ evt.data+&#39;&#39;);
        // websocket.close();
    }

    function onError(evt) {
        writeToScreen(&#39;<span style="color: red;">ERROR: &#39;+ evt.data);
    }

    function doSend(message) {
        // writeToScreen("SENT: " + message);
        websocket.send(message);
    }

    function writeToScreen(message) {
        var pre = document.createElement("p");
        pre.style.wordWrap = "break-word";
        pre.innerHTML = message;
        output.appendChild(pre);
    }

    window.addEventListener("load", init, false);
    function sendBtnClick(){
        var msg = document.getElementById("input").value;
        doSend(msg);
        document.getElementById("input").value = &#39;&#39;;
    }
    function closeBtnClick(){
        websocket.close();
    }
</script><h2>WebSocket Test</h2>
<input><button>send</button>
<button>close</button>
<div></div>


声明:本文转载于:learnku,如有侵犯,请联系admin@php.cn删除