博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go-iris-websocket 简单聊天通信
阅读量:2087 次
发布时间:2019-04-29

本文共 5718 字,大约阅读时间需要 19 分钟。

基于go的websocket大多使用gorilla/websocket

iris也提供了websoket的封装,github.com/kataras/iris/v12/websocket

不过iris官方给的示例基本上都是依赖官方的js库实现的neffos.js

Neffos.js对websocket进行了封装,主要是房间进入和离开等事件的绑定,

对于消息的传递也使用了自己定义的格式,不同的字段使用分号进行分割

例如:;;;;0;0;helloworld,查看iris中源码看到Message的定义:

type Message struct {
wait string// The Namespace that this message sent to/received from.Namespace string// The Room that this message sent to/received from.Room string// The Event that this message sent to/received from.Event string// The actual body of the incoming/outcoming data.Body []byte// The Err contains any message's error, if any.// Note that server-side and client-side connections can return an error instead of a message from each event callbacks,// except the clients's force Disconnect which its local event doesn't matter when disconnected manually.Err error// if true then `Err` is filled by the error message and// the last segment of incoming/outcoming serialized message is the error message instead of the body.isError boolisNoOp boolisInvalid bool// the CONN ID, filled automatically if `Server#Broadcast` first parameter of sender connection's ID is not empty,// not exposed to the subscribers (rest of the clients).// This is the ID across neffos servers when scale.from string// When sent by the same connection of the current running server instance.// This field is serialized/deserialized but it's clean on sending or receiving from a client// and it's only used on StackExchange feature.// It's serialized as the first parameter, instead of wait signal, if incoming starts with 0x.FromExplicit string // the exact Conn's pointer in this server instance.// Reports whether this message is coming from a stackexchange.// This field is not exposed and it's not serialized at all, ~local-use only~.//// The "wait" field can determinate if this message is coming from a stackexchange using its second char,// This value set based on "wait" on deserialization when coming from remote side.// Only server-side can actually set it.FromStackExchange bool// To is the connection ID of the receiver, used only when `Server#Broadcast` is called, indeed when we only need to send a message to a single connection.// The Namespace, Room are still respected at all.//// However, sending messages to a group of connections is done by the `Room` field for groups inside a namespace or just `Namespace` field as usual.// This field is not filled on sending/receiving.To string// True when event came from local (i.e client if running client) on force disconnection,// i.e OnNamespaceDisconnect and OnRoomLeave when closing a conn.// This field is not filled on sending/receiving.// Err does not matter and never sent to the other side.IsForced bool// True when asking the other side and fire the respond's event (which matches the sent for connect/disconnect/join/leave),// i.e if a client (or server) onnection want to connect// to a namespace or join to a room.// Should be used rarely, state can be checked by `Conn#IsClient() bool`.// This field is not filled on sending/receiving.IsLocal bool// True when user define it for writing, only its body is written as raw native websocket message, namespace, event and all other fields are empty.// The receiver should accept it on the `OnNativeMessage` event.// This field is not filled on sending/receiving.IsNative bool// Useful rarely internally on `Conn#Write` namespace and rooms checks, i.e `Conn#DisconnectAll` and `NSConn#RemoveAll`.// If true then the writer's checks will not lock connectedNamespacesMutex or roomsMutex again. May be useful in the future, keep that solution.locked bool// if server or client should write using Binary message or if the incoming message was readen as binary.SetBinary bool}

注意到有个IsNative的控制参数,使用OnNativeMessage事件和IsNative字段就可以使用自己的格式通过websoket传递数据:

// True when user define it for writing, only its body is written as raw native websocket message, namespace, event and all other fields are empty.// The receiver should accept it on the `OnNativeMessage` event.// This field is not filled on sending/receiving.IsNative bool
msg:=websocket.Message{
Body:[]byte("helloworld"), IsNative:true,}

接下来使用iris/websocket实现简单的聊天通信,go主要代码如下:

ws := websocket.New(websocket.DefaultGorillaUpgrader, websocket.Events{
websocket.OnNativeMessage: func(nsConn *websocket.NSConn, msg websocket.Message) error {
log.Printf("Server got: %s from [%s]", msg.Body, nsConn.Conn.ID())ping := string(msg.Body)pong := strings.Replace(ping,"?", "!", len(ping))pong = strings.Replace(pong, "么","",len(pong))mg := websocket.Message{
Body:[]byte(pong),IsNative:true,}nsConn.Conn.Write(mg)return nil},})

完整go代码:

package mainimport (	"log"	"strings"	"github.com/kataras/iris/v12"	"github.com/kataras/iris/v12/websocket")func main() {
ws := websocket.New(websocket.DefaultGorillaUpgrader, websocket.Events{
websocket.OnNativeMessage: func(nsConn *websocket.NSConn, msg websocket.Message) error {
log.Printf("Server got: %s from [%s]", msg.Body, nsConn.Conn.ID()) ping := string(msg.Body) pong := strings.Replace(ping,"?", "!", len(ping)) pong = strings.Replace(pong, "么","",len(pong)) mg := websocket.Message{
Body:[]byte(pong), IsNative:true, } nsConn.Conn.Write(mg) return nil }, }) ws.OnConnect = func(c *websocket.Conn) error {
log.Printf("[%s] Connected to server!", c.ID()) return nil } ws.OnDisconnect = func(c *websocket.Conn) {
log.Printf("[%s] Disconnected from server", c.ID()) } ws.OnUpgradeError = func(err error) {
log.Printf("Upgrade Error: %v", err) } app := iris.New() app.HandleDir("/","./html") app.Get("/msg", websocket.Handler(ws)) app.Run(iris.Addr(":8080"))}

html 代码:

    Client Page

效果:

在这里插入图片描述

转载地址:http://cplqf.baihongyu.com/

你可能感兴趣的文章
Flink示例——Window、EventTime、WaterMark
查看>>
Flink示例——State、Checkpoint、Savepoint
查看>>
Flink示例——Table、SQL
查看>>
HBase之Rowkey设计
查看>>
推荐算法——ALS模型算法分析、LFM算法
查看>>
Spark源码剖析——RpcEndpoint、RpcEnv
查看>>
Spark源码剖析——Master、Worker启动流程
查看>>
TensorFlow2 学习——MLP图像分类
查看>>
TensorFlow2 学习——CNN图像分类
查看>>
Spark源码剖析——SparkSubmit提交流程
查看>>
TensorFlow2 学习——RNN生成古诗词
查看>>
Spark源码剖析——SparkContext实例化
查看>>
基于阿里云的数据仓库架构设计
查看>>
Docker——安装、常用命令、生成镜像(Dockerfile)
查看>>
Docker——部署(tomcat、nginx、负载均衡、常见问题)
查看>>
OpenCV学习——图像基础与几何变换
查看>>
OpenCV学习——图像特效
查看>>
Spark源码剖析——Action操作、runJob流程
查看>>
分布式——缓存一致性(Redis、MySQL)
查看>>
Gminer 配置参数
查看>>