Giter VIP home page Giter VIP logo

go-websocket's Introduction

Golang实现的分布式WebSocket微服务

Go GitHub release Travis (.org) star

简介

本系统基于Golang、ETCD、RPC实现分布式WebSocket微服务,也可以单机部署,单机部署不需要ETCD、RPC。分布式部署可以支持nginx负责均衡、水平扩容部署,程序之间使用RPC通信。

基本流程为:用ws协议连接本服务,得到一个clientId,由客户端上报这个clinetId给服务端,服务端拿到这个clientId之后,可以给这个客户端发送信息,绑定这个客户端都分组,给分组发送消息。

目前实现的功能有,给指定客户端发送消息、绑定客户端到分组、给分组里的客户端批量发送消息、获取在线的客户端、上下线自动通知。适用于长连接的大部分场景,分组可以理解为聊天室,绑定客户端到分组相当于把客户端添加到聊天室,给分组发送信息相当于给聊天室的每个人发送消息。

文档

  1. 技术方案架构
  2. 接口文档

SDK

  1. PHP版:https://github.com/woodylan/go-websocket-php-sdk

使用

下载本项目:

这里已经打包好了,下载相应的环境,支持Linux、Windows、MacOS环境。

https://github.com/woodylan/go-websocket/releases

你也可以选择自己编译:

git clone https://github.com/woodylan/go-websocket.git

编译:

// 编译适用于本机的版本
go build

// 编译Linux版本
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build

// 编译Windows 64位版本
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

// 编译MacOS版本
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build

执行:

编译成功之后会得到一个二进制文件go-websocket,执行该二进制文件。

./go-websocket -c ./conf/app.ini

连接测试:

打开支持Websocket的客户端,输入 ws://127.0.0.1:7800/ws?systemId=xxx 进行连接,连接成功会返回clientId

docker体验

体验单机

  1. 构建镜像

    docker build -t go-websocket .
  2. 基于镜像运行容器

    docker run -tid -p 7800:7800 go-websocket

体验集群,同时运行ETCD集群

在当前目录下,直接运行 docker-compose up 即可体验。

配置

配置文件:

配置文件位于项目根目录的conf/app.ini

[common]
HttpPort = 6000
RPCPort = 7000
# 是否集群,单机则设为false
Cluster = true
# 对称加密key 只允许16、24、32字节长度
CryptoKey = Adba723b7fe06819

[etcd]
Endpoints = 127.0.0.1:2379, 127.0.0.2:2379, 127.0.0.3:2379

运行项目:

在不同的机器运行本项目,注意配置号端口号,项目如果在同一机器,则必须用不同的端口。你可以用supervisor做进程管理。

配置Nginx负载均衡:

upstream ws_cluster {
    server 127.0.0.1:7800;
    #server 127.0.0.1:7801;
}

server {
    listen  7000;
    server_name ws.example.com;

    access_log /logs/access.log;
    error_log /logs/error.log;
    
    location /ws {
        proxy_pass http://ws_cluster; # 代理转发地址
        proxy_http_version 1.1;

        proxy_read_timeout 60s; # 超时设置

        # 启用支持websocket连接
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /api {
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host            $http_host;

        proxy_pass http://ws_cluster; # 代理转发地址
    }
}

至此,项目部署完成。

实现的功能

  • 分布式
  • 账户授权模式
  • 不同业务系统隔离
  • 发送给指定客户端
  • 发送给指定分组
  • 上下线通知
  • 群广播
  • 错误日志
  • 参数校验
  • 关闭某个连接
  • 支持docker
  • 查询某个客户端是否在线

沟通交流

QQ群:1028314856

Golang websocket分布式交流群

go-websocket's People

Contributors

dependabot[bot] avatar hhhha avatar wanyaoasiainfo avatar woodylan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-websocket's Issues

6000端口有毒

6000端口启动成功,但是路由访问不了,换了端口就可以正常访问!!!请大家闭坑,谷歌了一下,6000似乎是特殊端口。

上下线自动通知这个怎么使用?

我只看到api接口有得到在线列表,没见有自动通知呀.
配置里也没看到有自动通知的配置内容.

有谁知道这个功能怎么使用吗?我看文档说明是有这个功能的.
总不能每次都得到全部在线列表,然后再操作吧?

建议添加hook,提升业务能力.

ws只作为服务器,用户只需要以restful api操作,以webhook对ws数据进行处理,这样所有人可根据自身项目语言对接就可以.

这里需防止客户端异常断开链接导致groutine异常程序崩溃

func (c *Client) Read() {
go func() {
defer func() {
// 当 goroutine 退出时触发断开连接
Manager.DisConnect <- c
}()

	for {
		messageType, _, err := c.Socket.ReadMessage()
		if err != nil {
			// 检查是否是 WebSocket 连接正常关闭的错误
			if websocket.IsCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
				return
			}
			// 其他错误或网络问题也应该退出读取循环
			return
		}

		// 您可以根据需要处理不同类型的消息
		if messageType == websocket.PingMessage {
			// 对 Ping 消息做出反应,例如发送 Pong 消息
			_ = c.Socket.WriteMessage(websocket.PongMessage, nil)
		}
	}
}()

}

docker run -tid -p 7800:7800 go-websocket 失败

Unable to find image 'go-websocket:latest' locally
docker: Error response from daemon: pull access denied for go-websocket, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.

etcd服务注册和发现

//监听续租情况
func (this *ServiceReg) ListenLeaseRespChan() {
	for {
		select {
		case leaseKeepResp := <-this.keepAliveChan:
			if leaseKeepResp == nil {
				log.Error("已经关闭续租功能")
				return
			} else {
				//log.Info("续租成功")
			}
		}
	}
}

只是做到通知,假如A服务不提供了,grpc还是有可能调用到A这台服务器是吗,这里是否还要完善

请求失败,调试很久没有搞定

显示这些错误
服务器启动成功,端口号:6000
2021-12-09 00:03:10.941497 I | http: panic serving 127.0.0.1:44690: crypto/aes: invalid key size 0
goroutine 21 [running]:
net/http.(*conn).serve.func1(0xc0002b8000)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:1795 +0x139
panic(0xb23300, 0x12432a0)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/runtime/panic.go:679 +0x1b2
go-websocket/tools/util.GenClientId(0xc0000cba00, 0xc2e91a)
/home/travis/gopath/src/github.com/woodylan/go-websocket/tools/util/util.go:25 +0x164
go-websocket/servers.(*Controller).Run(0x1242090, 0xd2a780, 0xc0000c6380, 0xc0000cba00)
/home/travis/gopath/src/github.com/woodylan/go-websocket/servers/connect.go:50 +0x20d
net/http.HandlerFunc.ServeHTTP(0xc00028e390, 0xd2a780, 0xc0000c6380, 0xc0000cba00)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:2036 +0x44
net/http.(*ServeMux).ServeHTTP(0x1225380, 0xd2a780, 0xc0000c6380, 0xc0000cba00)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:2416 +0x1bd
net/http.serverHandler.ServeHTTP(0xc0000c62a0, 0xd2a780, 0xc0000c6380, 0xc0000cba00)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:2831 +0xa4
net/http.(*conn).serve(0xc0002b8000, 0xd2be40, 0xc00024cac0)
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:1919 +0x875
created by net/http.(*Server).Serve
/home/travis/.gimme/versions/go1.13.15.linux.amd64/src/net/http/server.go:2957 +0x384

manager.ClientIdMap设计有问题

manager.ClientIdMap的key clientId只是服务器的ip:port,如果新ws连接使用的ip:port相同则会覆盖旧key。结果:无法取得被覆盖的conn。
如果我理解错了,请让我知道,谢谢。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.