goland 实现websocket server的示例代码

采用go 实现的websocket,已经调试通过在此记录。

测试工具网址:https://www.idcd.com/tool/socket

话不多说上全部代码:

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	uuid "github.com/satori/go.uuid"
)

//Client:单个websocket
type Client struct {
	Id      string
	Socket  *websocket.Conn
	Message chan []byte
}

var clientCount   uint // 客户端数量

//从websocket中直接读取数据
func (c *Client) Read() {
	defer func() {
		//客户端关闭
		if err := c.Socket.Close(); err != nil {
			fmt.Printf("client [%s] disconnect err: %s", c.Id, err)
		}
		//关闭后直接注销客户端
		//WebsocketManager.UnRegisterClient(c)
		clientCount--
		fmt.Printf("client [%s],客户端关闭:[%s],Count [%d]\n", c.Id, websocket.CloseMessage, clientCount)
	}()

	for {
		messageType, message, err := c.Socket.ReadMessage()
		//读取数据失败
		if err != nil || messageType == websocket.CloseMessage {
			fmt.Printf("client [%s],数据读取失败或通道关闭:[%s],客户端连接状态:[%s]\n", c.Id, err.Error(), websocket.CloseMessage)
			break
		}

		// TODO 解析发送过来的参数
		//var data ReadData
		//err = json.Unmarshal(message, &data)
		//if err != nil {
		//  fmt.Println("数据解析失败")
		//	return
		//}

		// TODO 前端请求返回数据到指定客户端

		// 简单测试
		c.Message <- message

	}
}

//写入数据到websocket中
func (c *Client) Write() {
	defer func() {
		//客户端关闭
		if err := c.Socket.Close(); err != nil {
			fmt.Printf("client [%s] disconnect err: %s \n", c.Id, err)
			return
		}
		//关闭后直接注销客户端
		//WebsocketManager.UnRegisterClient(c)
		clientCount--
		fmt.Printf("client [%s],客户端关闭:[%s]\n", c.Id, websocket.CloseMessage)
	}()

	for {
		select {
		case message, ok := <-c.Message:

			if !ok {
				//数据写入失败,关闭通道
				fmt.Printf("client [%s],客户端连接状态:[%s]\n", c.Id, websocket.CloseMessage)
				_ = c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				//消息通道关闭后直接注销客户端
				return
			}

			err := c.Socket.WriteMessage(websocket.TextMessage, message)
			if err != nil {
				fmt.Printf("client [%s] write message err: %s \n", c.Id, err)
				return
			}
		}
	}
}

// 方法二: 通过对象创建  客户端连接
func WsClient(context *gin.Context) {
	upGrande := websocket.Upgrader{
		//设置允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		//设置请求协议
		Subprotocols: []string{context.GetHeader("Sec-WebSocket-Protocol")},
	}
	//创建连接
	conn, err := upGrande.Upgrade(context.Writer, context.Request, nil)
	if err != nil {
		fmt.Printf("websocket connect error: %s", context.Param("channel"))
		//format.NewResponseJson(context).Error(51001)
		return
	}
	//生成唯一标识client_id
	var uuid = uuid.NewV4().String()
	client := &Client{
		Id:      uuid,
		Socket:  conn,
		Message: make(chan []byte, 1024),
	}
	//注册
	//ws.WebsocketManager.RegisterClient(client)
	clientCount++

	//起协程,实时接收和回复数据
	go client.Read()
	go client.Write()
}

// 方法一: 直接创建客户端
func NewConnection(c *gin.Context) {
	// 定义同源检查,这里只作简单试验不校验
	upGrader := websocket.Upgrader{
	   CheckOrigin: func(r *http.Request) bool {
	       return true
	   },
	}
	 ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	//ws, err := websocket.Upgrade(c.Writer, c.Request, nil, 1024, 1024)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"msg": "服务端错误",
		})
		return
	}

	var message = make(chan []byte)

	go func() {
		defer ws.Close()

		for {
			fmt.Println("start transfer message")
			msgType, msg, err := ws.ReadMessage()
			if err != nil || websocket.CloseMessage == msgType {
				fmt.Println("webSocket read error")
				return
			}
			message <- msg
		}

	}()

	go func() {
		defer ws.Close()

		for {
			mm, ok := <- message

			if !ok {
				//数据写入失败,关闭通道
				fmt.Printf("客户端连接状态:[%s]\n", websocket.CloseMessage)
				_ = ws.WriteMessage(websocket.CloseMessage, []byte{})
				//消息通道关闭后直接注销客户端
				return
			}

			err := ws.WriteMessage(websocket.TextMessage, mm)
			if err != nil {
				fmt.Println("webSocket write error")
				return
			}
		}
	}()

	//for {
	//
	//}

	 开始通信
	//for {
	//	fmt.Println("start transfer message")
	//	msgType, msg, err := ws.ReadMessage()
	//	if err != nil {
	//		fmt.Println("webSocket read error")
	//		return
	//	}
	//	err = ws.WriteMessage(msgType, msg)
	//	if err != nil {
	//		fmt.Println("webSocket write error")
	//		return
	//	}
	//}
}

// ws://127.0.0.1:9090/wsTest
func main() {
	r := gin.Default()

	// 方法一: 直接创建客户端
	r.GET("/wsTest", NewConnection)
	// 方法二: 通过对象创建  客户端连接
	r.GET("/wsTest1", WsClient)

	clientCount = 0
	r.Run("127.0.0.1:9090")
}

拷贝全部代码到工程即可测试。

到此这篇关于goland 实现websocket server的示例代码的文章就介绍到这了,更多相关goland 实现websocket server内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 利用 Go 语言编写一个简单的 WebSocket 推送服务

    本文中代码可以在 github.com/alfred-zhong/wserver获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息都是通过短信,微信和 App 推送给用户的,现在要让登录用户在网页端也能实时接收到报警推送. 依稀记得以前工作的时候遇到过类似的需求.因为以前的浏览器标准比较陈旧,并且那时用 Java 较多,所以那时候解决这个问题就用了 Comet4J.具体的原理就是长轮询,长链接.但现在毕竟 html5 流行开来了,IE 都被 Edge 接替了,再用以前这种技术就显得过

  • golang websocket 服务端的实现

    创建一个websocket的服务端 package smile import ( "errors" "log" "net/http" "sync" "time" "github.com/gorilla/websocket" ) const ( // 允许等待的写入时间 writeWait = 10 * time.Second // Time allowed to read the nex

  • 使用Go语言创建WebSocket服务的实现示例

    今天介绍如何用 Go 语言创建 WebSocket 服务,文章的前两部分简要介绍了 WebSocket 协议以及用 Go 标准库如何创建 WebSocket 服务.第三部分实践环节我们使用了 gorilla/websocket 库帮助我们快速构建 WebSocket 服务,它帮封装了使用 Go 标准库实现 WebSocket 服务相关的基础逻辑,让我们能从繁琐的底层代码中解脱出来,根据业务需求快速构建 WebSocket 服务. Go Web 编程系列的每篇文章的源代码都打了对应版本的软件包,供

  • 利用Go语言搭建WebSocket服务端方法示例

    Go 搭建一个简单 WebSocket 服务端代码例子 test.go, 如下: package main import ( "fmt" "log" "net/http" "golang.org/x/net/websocket" ) func Echo(ws *websocket.Conn) { var err error for { var reply string if err = websocket.Message.Re

  • Golang使用WebSocket通信的实现

    使用Golang能够创建WebSocket通信,只需要使用golang.org/x/net/websocket包即可,该包有可能被墙,无法使用go get下载,但是我们可以从golang中国提供的地址下载,然后将包放在对应的路径下. WebSocket是一种通信协议,旨在改善HTTP作为无状态协议通信的效率问题,WebSocket是客户端与服务器之间的全双工连接,客户端和服务器只需要建立一次连接就可以使用该连接进行通信.在我们的项目中,一般客户端是前端页面,使用JavaScript创建WebSo

  • Go 实现百万WebSocket连接的方法示例

    大家好!我是 Sergey Kamardin,是 Mail.Ru 的一名工程师. 本文主要介绍如何使用 Go 开发高负载的 WebSocket 服务. 如果你熟悉 WebSockets,但对 Go 了解不多,仍希望你对这篇文章的想法和性能优化方面感兴趣. 1. 简介 为了定义本文的讨论范围,有必要说明我们为什么需要这个服务. Mail.Ru 有很多有状态系统.用户的电子邮件存储就是其中之一.我们有几种方法可以跟踪该系统的状态变化以及系统事件,主要是通过定期系统轮询或者状态变化时的系统通知来实现.

  • go的websocket实现原理与用法详解

    本文实例讲述了go的websocket实现原理与用法.分享给大家供大家参考,具体如下: websocket分为握手和数据传输阶段,即进行了HTTP握手 + 双工的TCP连接 RFC协议文档在:http://tools.ietf.org/html/rfc6455 握手阶段 握手阶段就是普通的HTTP 客户端发送消息: GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebS

  • golang基于websocket实现的简易聊天室程序

    本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

  • goland 实现websocket server的示例代码

    采用go 实现的websocket,已经调试通过在此记录. 测试工具网址:https://www.idcd.com/tool/socket 话不多说上全部代码: package main import ( "fmt" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "net/http" uuid "github.com/satori/go.uuid&

  • Django+Vue实现WebSocket连接的示例代码

    近期有一需求:前端页面点击执行任务,实时显示后端执行情况,思考一波:发现 WebSocket 最适合做这件事. 效果 测试 ping www.baidu.com 效果 点击连接建立ws连接 后端实现 所需软件包 后端主要借助Django Channels 实现socket连接,官网文档链接 这里想实现每个连接进来加入组进行广播,所以还需要引入 channels-redis . pip channels==2.2.0 channels-redis==2.4.0 引入 settings.py INS

  • C++编写的WebSocket服务端客户端实现示例代码

    目录 使用过标准的libwebsockets服务端库测试过,主要是短小精悍,相对于libwebsockets不需要依赖zlib和openssl 以及其他库,直接make就可以使用了,linux跟windows都可以使用. 测试用例: #include "easywsclient.hpp" #include <assert.h> #include <stdio.h> #include <string> using easywsclient::WebSo

  • 微信小程序websocket聊天室的实现示例代码

    背景 最近做了一个微信小程序的即时通讯功能,之前我也做过node.js的websocket服务,不过是在web端应用的socket.io服务.小程序本身对http.websocket等连接均有诸多限制,所以这次项目选择了node.js自带的ws模块. 服务端 初始化一个node.js项目,引入ws模块 const webSocket = require('ws'); 创建websocket实例,并设置监听端口 const wss = new webSocket.Server({ port: 30

  • SpringBoot+WebSocket+Netty实现消息推送的示例代码

    上一篇文章讲了Netty的理论基础,这一篇讲一下Netty在项目中的应用场景之一:消息推送功能,可以满足给所有用户推送,也可以满足给指定某一个用户推送消息,创建的是SpringBoot项目,后台服务端使用Netty技术,前端页面使用WebSocket技术. 大概实现思路: 前端使用webSocket与服务端创建连接的时候,将用户ID传给服务端 服务端将用户ID与channel关联起来存储,同时将channel放入到channel组中 如果需要给所有用户发送消息,直接执行channel组的writ

  • SpringBoot+Netty+WebSocket实现消息发送的示例代码

    一.导入Netty依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.25.Final</version> </dependency> 二.搭建websocket服务器 @Component public class WebSocketServer { /** * 主线程池 */

  • Springboot+WebSocket实现一对一聊天和公告的示例代码

    1.POM文件导入Springboot整合websocket的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>2.1.6.RELEASE</version> </dependency> 2.注册WebSocket的

  • SpringBoot实现WebSocket即时通讯的示例代码

    目录 1.引入依赖 2.WebSocketConfig 开启WebSocket 3.WebSocketServer 4.测试连接发送和接收消息 5.在线测试地址 6.测试截图 1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>

  • SpringBoot整合Netty实现WebSocket的示例代码

    目录 一.pom.xml依赖配置 二.代码 2.1.NettyServer 类 2.2.SocketHandler 类 2.3.ChannelHandlerPool 类 2.4.Application启动类 三.测试 一.pom.xml依赖配置 <!-- netty --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <v

  • SQL server数据库创建代码 filegroup文件组修改的示例代码

    数据库的操作: 1. 对数据文件的操作(添加,删除,修改文件的初始大小,最大大小,步长) 2. 数据库文件的收缩 3. 数据库的只读/读写   read_only只读   read_write可读写   read_only表示只读  read_write表示可读可写 4. 数据库的限制访问(单用户,多用户,限制用户模式) 5.数据库脱机/联机    offline  脱机 alter database love set offline      online 联机    alter databa

随机推荐