golang语言websocket百万长链接

这篇具有很好参考价值的文章主要介绍了golang语言websocket百万长链接。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

是简单demo测试

前端

<html>
<head>
    <title>Simple client</title>

    <script type="text/javascript">
        var ws;

        function init() {
            // Connect to Web Socket
            ws = new WebSocket("ws://localhost:8866/ws");
            // Set event handlers.
            ws.onopen = function() {
                output("onopen");
            };

            ws.onmessage = function(e) {
                // e.data contains received string.
                output("onmessage: " + e.data);
            };

            ws.onclose = function() {
                output("onclose");
            };
            ws.onerror = function(e) {
                output("onerror");
                console.log(e)
            };
        }

        function onSubmit() {
            var input = document.getElementById("input");
            // You can send message to the Web Socket using ws.send.
            ws.send(input.value);
            output("send: " + input.value);
            input.value = "";
            input.focus();
        }

        function onCloseClick() {
            ws.close();
        }

        function output(str) {
            var log = document.getElementById("log");
            var escaped = str.replace(/&/, "&amp;").replace(/</, "&lt;").
            replace(/>/, "&gt;").replace(/"/, "&quot;"); // "
            log.innerHTML = escaped + "<br>" + log.innerHTML;
        }
    </script>
</head>
<body onload="init();">
<form onsubmit="onSubmit(); return false;">
    <input type="text" id="input">
    <input type="submit" value="Send">
    <button onclick="onCloseClick(); return false;">close</button>
</form>
<div id="log"></div>
</body>
</html>

后端

主服务

package main

import (
	"bytes"
	"github.com/gorilla/websocket"
	"net/http"
	"time"
	"websocket/impl"
)

func main() {
	http.HandleFunc("/ws", wsHandle)

	http.ListenAndServe("0.0.0.0:8866", nil)
}

//定义转换器
var (
	upgrader = websocket.Upgrader{
		//允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

func wsHandle(w http.ResponseWriter, r *http.Request) {
	var (
		wsConn *websocket.Conn
		err    error
		data   []byte
		conn   *impl.Connection
	)

	if wsConn, err = upgrader.Upgrade(w, r, nil); err != nil {
		return
	}
	if conn, err = impl.InitConnetion(wsConn); err != nil {
		goto ERR
	}
	go func() {
		var (
			err error
		)
		for {
			if err = conn.WriteMessage([]byte("heartbeat")); err != nil {
				return
			}
			time.Sleep(5 * time.Second)
		}
	}()

	for {
		if data, err = conn.ReadMessage(); err != nil {
			goto ERR
		}
		if err = conn.WriteMessage(data); err != nil {
			goto ERR
		}
	}
ERR:
	//todo关闭连接操作
	conn.Close()
}

func BytesCombine1(pBytes ...[]byte) []byte {
	length := len(pBytes)
	s := make([][]byte, length)
	for index := 0; index < length; index++ {
		s[index] = pBytes[index]
	}
	sep := []byte("")
	return bytes.Join(s, sep)
}

接口封装

package impl

import (
	"errors"
	"github.com/gorilla/websocket"
	"sync"
)

type Connection struct {
	wsConn       *websocket.Conn
	inChannel    chan []byte
	outChannel   chan []byte
	closeChannel chan byte
	isClose      bool
	mutex        sync.Mutex
}

func InitConnetion(wsConn *websocket.Conn) (conn *Connection, err error) {
	conn = &Connection{
		wsConn:       wsConn,
		inChannel:    make(chan []byte, 1000),
		outChannel:   make(chan []byte, 1000),
		closeChannel: make(chan byte, 1),
	}
	//读协程
	go conn.readLoop()
	go conn.writeLoop()
	return
}
func (conn *Connection) ReadMessage() (data []byte, err error) {
	select {
	case data = <-conn.inChannel:
	case <-conn.closeChannel:
		err = errors.New("connection 已关闭")

	}
	return
}

func (conn *Connection) WriteMessage(data []byte) (err error) {

	select {
	case conn.outChannel <- data:
	case <-conn.closeChannel:
		err = errors.New("connection 已关闭")

	}
	return
}

func (conn *Connection) Close() {
	conn.wsConn.Close()
	if !conn.isClose {
		close(conn.closeChannel)
		conn.isClose = true
	}
	conn.mutex.Unlock()
}

//内部实现
func (conn *Connection) readLoop() {
	var (
		data []byte
		err  error
	)

	for {
		select {
		case conn.inChannel <- data:
		case <-conn.closeChannel:
			goto ERR

		}
		if _, data, err = conn.wsConn.ReadMessage(); err != nil {
			goto ERR
		}

		conn.inChannel <- data
	}
ERR:
	conn.Close()
}

func (conn *Connection) writeLoop() {
	var (
		data []byte
		err  error
	)
	for {
		data = <-conn.outChannel
		if conn.wsConn.WriteMessage(websocket.TextMessage, data); err != nil {
			goto ERR
		}
	}
ERR:
	conn.Close()
}

效果

golang语言websocket百万长链接

优化

内核瓶颈

cup 最理想的处理大概是每秒100万次,已经到了极限文章来源地址https://www.toymoban.com/news/detail-412397.html

  1. 减少网络小包的发送,小包大概几百字节,把同一秒中的推送的条数合并成一条,合并后每秒推送的次数等于连接数

锁瓶颈

  1. 打包json

到了这里,关于golang语言websocket百万长链接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • golang语言中简单操作es几个例子

     使用库(olivere/elastic/v7)操作es 1、初始化es操作客户端 2、使用must查询数据 3、terms、matchPhraseQuery、rangeQuery 4、查询后,根据字段排序

    2024年02月11日
    浏览(38)
  • Springboot 项目中引入WebSocket后,单元测试出现错误,前端开发揭秘

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) at org.springframework.test.context.w

    2024年04月27日
    浏览(36)
  • springboot-简单测试 前端上传Excel表格后端解析数据

    后端返回数据

    2024年01月20日
    浏览(41)
  • 推荐运维神器HSS工具,简单批量管理百万linux机器

    HSS(Host Shell Service)解决的主要痛点是在多台服务器上执行命令时的繁琐操作和安全性问题。 在传统的方式下,需要分别登录每一台服务器,逐一执行需要的命令 。这种方式存在以下痛点: 繁琐操作:登录多台服务器需要逐一输入用户名和密码,比较繁琐,而且执行命令也

    2024年02月05日
    浏览(82)
  • Golang 搭建 WebSocket 应用(一) - 初识 gorilla/websocket

    在本系列文章中,将会使用在 Go 中一个用得比较多的 WebSocket 实现 gorilla/websocket。 本文会涉及到一些原理讲解,其中比较关键的一个是 HTTP 与 WebSocket 的联系与区别,了解这个可以帮助我们更好地使用 WebSocket 。 如果我们此前已经使用过 WebSocket ,比如在 nginx 配置过 WebSocke

    2024年01月21日
    浏览(45)
  • 使用EasyExcel实现excel导出,支持百万大数据量导出-----超简单

    通过设置sheet数量,完成分批导出,每个sheet存100万数据,每次查询插入20万数据,避免超时,内存溢出等问题,可以根据服务器配置调整参数设置。 1.引入依赖 2.创建对应的实体类 @ExcelProperty设置的就是导出的列名,还可以设置排序等等 3.核心导出代码 4.配置类 至此就完成导

    2024年02月11日
    浏览(62)
  • 长/短 链接/轮询 和websocket

    短连接 : http协议底层基于socket的tcp协议,每次通信都会新建一个TCP连接,即每次请求和响应过程都经历”三次握手-四次挥手“ 优点:方便管理 缺点:频繁的建立和销毁连接占用资源 长连接 : 客户端和服务端之间只有一条TCP通信连接,以后所有的请求都使用这条连接,也

    2024年02月10日
    浏览(33)
  • golang Gin实现websocket

    golang使用 Gin实现 websocket,这里笔者重新搭建一个项目 项目名为 go-gin-websocket 在指定文件夹下,新建项目文件夹 go-gin-websocket 进入项目文件夹,打开cmd窗口,在项目(go-gin-websocket)文件夹路径下,执行初始化命令 go mod init go-gin-websocket 安装依赖 安装gin  安装websocket 在项

    2024年02月06日
    浏览(49)
  • Golang WebSocket 创建单独会话

    在互联网应用程序中,实时通信是一种非常重要的功能。WebSocket 是一种基于 TCP 的协议,它允许客户端和服务器之间进行双向通信。Golang 是一种高性能的编程语言,它提供了对 WebSocket 的原生支持,使得在 Golang 中创建 WebSocket 会话变得非常简单。本文将介绍如何使用 Golang 创

    2024年02月08日
    浏览(37)
  • C语言爬虫采集图书网站百万数据

    最近需要查阅一些资料,只给到相关项目名称以及,想通过图书文库找到对应书籍,那么怎么才能在百万数据库中找到自己需要的文献呢? 今天我依然用C语言写个爬虫程序,从百万数据库中查找到适合的文章,能节省很多事情。 下面是一个简单的C#爬虫程序,它使用

    2024年01月21日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包