websocket

websocket.Upgrader升级为websocket协议

服务端

package main

import (
"fmt"
"net/http"
"unsafe" "github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
//设置websocket
//CheckOrigin防止跨站点的请求伪造
var upGrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
} //websocket实现
func ping(c *gin.Context) {
//升级get请求为webSocket协议
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
return
}
defer ws.Close() //返回前关闭
for {
//读取客户端发送来到消息
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
fmt.Println("服务端收到消息:",string(message))
fmt.Println("mt类型:",mt)
//写入ws数据
T:=string(message) +"收到"
msg:=*(*[]byte)(unsafe.Pointer(&T)) //服务端发送消息到客户端websocket
err = ws.WriteMessage(mt, msg)
if err != nil {
break
}
fmt.Println("发送消息:",T)
}
} func main() {
r := gin.Default()
r.GET("/ping", ping)
r.Run(":8080")
}

客户端

package main

import (
"fmt"
"log"
"net/url"
"strconv"
"sync"
"time" "github.com/gorilla/websocket"
) type websocketClientManager struct {
conn *websocket.Conn
addr *string
path string
sendMsgChan chan string
recvMsgChan chan string
isAlive bool
timeout int
} // 构造函数
func NewWsClientManager(addrIp, addrPort, path string, timeout int) *websocketClientManager {
addrString := addrIp + ":" + addrPort
var sendChan = make(chan string, 10) //定义channel大小,需要及时处理消费,否则会阻塞
var recvChan = make(chan string, 10) //定义channel大小,需要及时处理消费,否则会阻塞
var conn *websocket.Conn
return &websocketClientManager{
addr: &addrString,
path: path,
conn: conn,
sendMsgChan: sendChan,
recvMsgChan: recvChan,
isAlive: false,
timeout: timeout,
}
} // 链接服务端
func (wsc *websocketClientManager) dail() {
var err error
u := url.URL{Scheme: "ws", Host: *wsc.addr, Path: wsc.path}
fmt.Println("connecting to:", u.String())
wsc.conn, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
fmt.Println(err)
return
}
wsc.isAlive = true
log.Printf("connecting to %s 链接成功!!!", u.String()) } // 发送消息到服务端
func (wsc *websocketClientManager) sendMsgThread() {
go func() {
for {
msg := <-wsc.sendMsgChan
fmt.Println("发送消息:",msg)
// websocket.TextMessage类型
err := wsc.conn.WriteMessage(websocket.TextMessage, []byte(msg))
if err != nil {
fmt.Println("write:", err)
continue
}
}
}()
} // 读取服务端消息
func (wsc *websocketClientManager) readMsgThread() {
go func() {
for {
if wsc.conn != nil {
_, message, err := wsc.conn.ReadMessage()
if err != nil {
log.Println("readErr:", err)
wsc.isAlive = false
// 出现错误,退出读取,尝试重连
break
}
// 需要读取数据,不然会阻塞
wsc.recvMsgChan <- string(message) }
}
}()
} // 开启服务并重连
func (wsc *websocketClientManager) start() {
for {
if wsc.isAlive == false {
wsc.dail()
wsc.sendMsgThread()
wsc.readMsgThread()
wsc.Msg() //构造假消息
wsc.Recv() //接收处理服务端返回到消息
}
time.Sleep(time.Second * time.Duration(wsc.timeout))
}
} //模拟websocket心跳包,假数据
func (wsc *websocketClientManager)Msg() {
go func() {
a:=0
for {
wsc.sendMsgChan <- strconv.Itoa(a)
time.Sleep(time.Second*1)
a+=1
}
}()
} //接收处理服务端返回到消息
func (wsc *websocketClientManager) Recv() {
go func() {
for {
msg, ok := <-wsc.recvMsgChan
if ok {
fmt.Println("收到消息:",msg)
}
}
}()
} func main() {
wsc := NewWsClientManager("127.0.0.1", "8080", "/ping", 10)
wsc.start() var w1 sync.WaitGroup
w1.Add(1)
w1.Wait()
}

go-websocket服务端/客户端的更多相关文章

  1. C# WebSocket 服务端示例代码 + HTML5客户端示例代码

    WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...

  2. socket-WebSocket HttpListener TcpListener 服务端客户端的具体使用案例

    /// <summary>/// 启动服务监听的ip和端口的主线程/// </summary>/// <param name="tunnelPort" ...

  3. socket-WebSocket-HttpListener-TcpListener服务端客户端的具体使用案例

    /// <summary> /// 启动服务监听的ip和端口的主线程 /// </summary> /// <param name="tunnelPort&qu ...

  4. nodejs搭建简单的websocket服务端

    创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...

  5. WebSocket服务端

    http://blog.csdn.net/qq_20282263/article/details/54310737 C# 实现WebSocket服务端 原创 2017年01月10日 09:22:50 ...

  6. asp.net网站作为websocket服务端的应用该如何写

    最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务.客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息. 其实,这个需求并不难,只是 ...

  7. Netty 搭建 WebSocket 服务端

    一.编码器.解码器 ... ... @Autowired private HttpRequestHandler httpRequestHandler; @Autowired private TextW ...

  8. react服务端/客户端,同构代码心得

    FKP-REST是一套全栈javascript框架   react服务端/客户端,同构代码心得 作者:webkixi react服务端/客户端,同构代码心得 服务端,客户端同构一套代码,大前端的梦想, ...

  9. 基于JAX-WS的Web Service服务端/客户端 ;JAX-WS + Spring 开发webservice

    一.基于JAX-WS的Web Service服务端/客户端 下面描述的是在main函数中使用JAX-WS的Web Service的方法,不是在web工程里访问,在web工程里访问,参加第二节. JAX ...

随机推荐

  1. 什么是 Spring Profiles?

    Spring Profiles 允许用户根据配置文件(dev,test,prod 等)来注册 bean.因此,当应用程序在开发中运行时,只有某些 bean 可以加载,而在 PRODUCTION中,某些 ...

  2. 面试问题之C++语言:说一说C++中四种cast转换

    C++中四种类型转换是:static_cast.dynamic_cast.const_cast.reinterpret_cast 1.const_cast 常量转换,用于将const变量转为非cons ...

  3. 面试问题之计算机网络:TCP滑动窗口

    滑动窗口协议是传输层进行流量控制的一种措施,接收方通过通知发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的,并且滑动窗口分为接收窗口和发送窗口.TC ...

  4. Spring的@Enable*注解的工作原理

    转自:https://blog.csdn.net/chengqiuming/article/details/81586948 一 列举几个@Enable*注解的功能 @EnableAspectJAut ...

  5. Streamlit:快速数据可视化界面工具

    目录 Streamlit简介 Streamlit使用指南 常用命令 显示文本 显示数据 显示图表 显示媒体 交互组件 侧边栏 缓存机制 Streamlit使用Hack Streamlit的替代品 相关 ...

  6. 【promise| async/await】代码的控制力

    什么样的代码好控制? 结构 + 节奏 --- 什么鬼? 如何控制节奏? 具体例子看看怎么控制节奏?

  7. 用Canvas画一棵二叉树

    笔墨伺候 var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // 然后便可以挥毫泼墨 ...

  8. 【weex开发】环境配置流程

    1,安装node.js node官网下载,然后安装即可. 安装完成以后可以查看node和npm版本 $ node -v v6.11.3 $ npm -v 3.10.10 2,安装weex-toolki ...

  9. Promise原理实现(一):前置知识点

      实现promise首先需要了解如下知识点: 1: 高阶函数 (一个函数作为另外一个函数的参数,这个包含的函数就是高阶函数): outer是一个高阶函数,inner函数作为一个参数传递:此处也是闭包 ...

  10. 关于表达式&& 和 || 有多项的时候的取值

    && 表达式只有两项的时候,如果表达式为false, 返回为false 的那一个 ,为true的时候    返回最后一个值 ||  只有两项的时候,返回为true 的那一个;都为fal ...