20、接入websocket并实现最基础的文字通讯

一、完成webscoket协议

1.新建controller/chat.go

20、接入websocket并实现最基础的文字通讯 - 图1

2.在main的go中定义一个路由,形成映射关系 

20、接入websocket并实现最基础的文字通讯 - 图2

二、实现controller/chat.go的Chat方法

首先下载webscoket相关包go get -u github.com/golang/net/webscoket

 

websocket包下载指令go get github.com/gorilla/websocket 

下载 第三方集合包go get -u gopkg.in/fatih/set.v0 

package controller
import (
    "fmt"
    "github.com/gorilla/websocket"
    "gopkg.in/fatih/set.v0"
    "log"
    "net/http"
    "strconv"
    "sync"
)
// 本核心在于形成userid和Node的映射关系
type Node struct {
    Conn *websocket.Conn
    //并行转串行,
    DataQueue chan []byte
    GroupSets set.Interface
}
// 映射关系表
var clientMap map[int64]*Node = make(map[int64]*Node, 0)
// 读写锁
var rwlocker sync.RWMutex
// ws://127.0.0.1/chat?id=1&token=xxxx
func Chat(writer http.ResponseWriter,
    request *http.Request) {
    //todo 检验接入是否合法
    //checkToken(userId int64,token string)
    //request.URL.Query() 获取url中所有数据
    query := request.URL.Query()
    id := query.Get("id")
    token := query.Get("token")
    //获取的数据都是字符串,需要做整型
    userId, _ := strconv.ParseInt(id, 10, 64)
    isvalida := checkToken(userId, token)
    //如果isvalida=true
    //isvalida=false   这是一般的处理方法
    //在webscoket中有处理方法
    conn, err := (&websocket.Upgrader{
        CheckOrigin: func(r *http.Request) bool {
            return isvalida
        },
    }).Upgrade(writer, request, nil)
    //如果有错直接打印出来
    if err != nil {
        log.Println(err.Error())
        return
    }
    //todo 获得conn
    node := &Node{
        Conn:      conn,
        DataQueue: make(chan []byte, 50),
        GroupSets: set.New(set.ThreadSafe),
    }
    //todo userid和node形成绑定关系
    rwlocker.Lock() //操作数据量比较大,所以添加了读写锁
    clientMap[userId] = node
    rwlocker.Unlock()
    //todo 完成发送逻辑,con
    go sendproc(node)
    //todo 完成接收逻辑
    go recvproc(node)
    //
    sendMsg(userId, []byte("hello,world!"))
}
// 发送协程
func sendproc(node *Node) {
    for {
        select {
        case data := <-node.DataQueue:
            err := node.Conn.WriteMessage(websocket.TextMessage, data)
            if err != nil {
                log.Println(err.Error())
                return
            }
        }
    }
}
// 接收协程
func recvproc(node *Node) {
    for {
        _, data, err := node.Conn.ReadMessage()
        if err != nil {
            log.Println(err.Error())
            return
        }
        //todo 对data进一步处理
        fmt.Printf("recv<=%s", data)
    }
}
// todo 发送消息
func sendMsg(userId int64, msg []byte) {
    rwlocker.RLock() //读写锁为了保证并发的安全性
    node, ok := clientMap[userId]
    rwlocker.RUnlock()
    if ok {
        node.DataQueue <- msg
    }
}
// 检测是否有效
func checkToken(userId int64, token string) bool {
    //从数据库里面查询并比对
    user := userService.Find(userId)
    return user.Token == token
}

 

三、实现service/user.go的Find方法

20、接入websocket并实现最基础的文字通讯 - 图6

四、前端websocket初始化

20、接入websocket并实现最基础的文字通讯 - 图7

五、进行测试一下

20、接入websocket并实现最基础的文字通讯 - 图8

如上就是接入websocket成功

 

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值