开箱即用的基于命令的消息处理框架,让 websocket 和 tcp 开发就像 http 那样简单

Cmd Srv

Build Status Go Doc Code Coverage License

开箱即用的基于命令的消息处理框架,让 websocket 和 tcp 开发就像 http 那样简单

使用示例

package main
import (
  "net/http"
  "github.com/eyasliu/cs"
  "github.com/eyasliu/cs/xwebsocket"
)

func main() {
  // 初始化 websocket
  ws := xwebsocket.New()
  http.Handle("/ws", ws)

  srv := ws.Srv()
  srv.Use(cs.AccessLogger("MYSRV")). // 打印请求响应日志
            Use(cs.Recover()) // 统一错误处理,消化 panic 错误

  srv.Handle("register", func(c *cs.Context) {
    // 定义请求数据
    var body struct {
      UID  int    `p:"uid" v:"required"`
      Name string `p:"name" v:"required|min:4#必需指定名称|名称长度必需大于4位"`
    }
    // 解析请求数据
    if err := c.Parse(&body); err != nil {
      c.Err(err, 401)
      return
    }
    // 设置会话状态数据
    c.Set("uid", body.UID)
    c.Set("name", body.Name)

    // 响应消息
    c.OK(map[string]interface{}{
      "timestamp": time.Now().Unix(),
    })

    // 给所有连接广播消息
    c.Broadcast(&cs.Response{
      Cmd:  "someone_online",
      Data: body,
    })

    // 往当前连接主动推送消息
    c.Push(&cs.Response{
      Cmd:  "welcome",
      Data: "welcome to register my server",
    })

    // 遍历所有在线会话,获取其他会话的状态,并往指定会话推送消息
    for _, sid := range c.GetAllSID() {
      if c.Srv.GetState(sid, "uid") != nil {
        c.Srv.Push(sid, &cs.Response{
          Cmd:  "firend_online",
          Data: "your firend is online",
        })
      }
    }
  })

  // 分组
  group := srv.Group(func(c *cs.Context) {
    // 过滤指定请求
    if _, ok := c.Get("uid").(int); !ok {
      c.Err(errors.New("unregister session"), 101)
      return
    }
    c.Next()
  })

  group.Handle("userinfo", func(c *cs.Context) {
    uid := c.Get("uid").(int) // 中间件已处理过,可大胆断言
    c.OK(map[string]interface{}{
      "uid": uid,
    })
  })
  go srv.Run()

  http.ListenAndServe(":8080", nil)
}

适配器

用在 websocket

import (
  "net/http"
  "github.com/eyasliu/cs/xwebsocket"
)

func main() {
  ws := xwebsocket.New()
  http.Handler("/ws", ws.Handler)
  srv := ws.Srv(ws)
  go srv.Run()

  http.ListenAndServe(":8080", nil)
}

用在 TCP,使用内置默认协议

import (
  "github.com/eyasliu/cs/xtcp"
)

func main() {
  server := xtcp.New("127.0.0.1:8520")
  srv, err := server.Srv()
  if err != nil {
    panic(err)
  }

  srv.Run() // 阻塞运行
}

使用 gnet, gnet 是一个性能非常高的网络框架,尤其在超高并发情况下性能更优,使用 gnet 作为 tcp 服务的底层框架

import (
  "github.com/eyasliu/cs/xgnet"
)

func main() {
  server := xgnet.New("127.0.0.1:8520")
  srv, err := server.Srv()
  if err != nil {
    panic(err)
  }

  srv.Run() // 阻塞运行
}

用在 HTTP,支持请求响应,支持服务器主动推送

import (
  "net/http"
  "github.com/eyasliu/cs"
  "github.com/eyasliu/cs/xhttp"
)

func main() {
  server := xhttp.New()
  http.Handle("/cmd", server)
  http.HandleFunc("/cmd2", server.Handler)
  srv := server.Srv()
  go http.ListenAndServe(":8080", nil)
	
  srv.Run()
}

多个适配器混用,让 websocket, tcp, http 共用同一套逻辑

import (
  "net/http"
  "github.com/eyasliu/cs"
  "github.com/eyasliu/cs/xhttp"
  "github.com/eyasliu/cs/xwebsocket"
  "github.com/eyasliu/cs/xtcp"
)

func main() {
  // http adapter
  server := xhttp.New()
  http.Handle("/cmd", server)
  http.HandleFunc("/cmd2", server.Handler)
  
  // websocket adapter
  ws := xwebsocket.New()
  http.Handle("/ws", server)

  // tcp adapter
  tcp := xtcp.New()

  // boot srv
  go tcp.Run()
  go http.ListenAndServe(":8080", nil)

  srv := cs.New(server, ws, tcp)
  srv.Run() // 阻塞运行
}
$ curl -XPOST -H"Content-Type:application/json" --data '{"cmd":"register", "data":{"uid": 101, "name": "eyasliu"}}' http://localhost:8080/cmd
{"cmd":"register","data":{"timestamp": 1610960488}}

实现过程

在开发 websocket 和 tcp 的时候,对于长连接的消息处理都需要手动处理,并没有类似于 http 的路由那么方便,于是就想要实现一个可以处理该类消息的工具。

在长连接的开发中,经常遇到的一些问题:

  1. 每个连接会话在连接后都需要注册,以标识该连接的用途
  2. 每个请求都需要处理,并且保证一定有响应
  3. 往连接主动推送消息
  4. 给所有连接广播消息
  5. 消息处理的代码不够优雅,太多 switch case 等样板代码
  6. 请求的数据解析不好写

实现方案:

在 websocket 和 tcp 中,每个连接都抽象成一个字符串 SID, 即 Session ID, cs 只负责处理消息,不处理连接的任何状态,与连接和状态相关的操作全都以 interface 定义好,给各种工具去实现

API

GoDoc

Similar Resources

TCP proxy, highjacks HTTP to allow CORS

portproxy A shitty TCP proxy that relays all requests to a local port to a remote server. portproxy -port 8080 -raddr google.com:80 Will proxy all TC

Jan 1, 2023

HTTP(S)/WS(S)/TCP Tunnels to localhost using only SSH.

An open source serveo/ngrok alternative.

Dec 29, 2022

Websockify-go - A reverse proxy that support tcp, http, https, and the most important, noVNC, which makes it a websockify

websockify-go | mproxy a reverse proxy that support tcp, http, https, and the mo

Aug 14, 2022

“Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server!

Dear Port80 About The Project: “Dear Port80” is a zero-config TCP proxy server that hides SSH connection behind a HTTP server! +---------------------

Jun 29, 2022

go websocket, a better way to buid your IM server

go websocket, a better way to buid your IM server

Your star is my power!! 🚀 ⭐ ⭐ ⭐ ⭐ ⭐ Discribe lhttp is a http like protocol using websocket to provide long live, build your IM service quickly scalab

Dec 30, 2022

Minimal and idiomatic WebSocket library for Go

websocket websocket is a minimal and idiomatic WebSocket library for Go. Install go get nhooyr.io/websocket Highlights Minimal and idiomatic API First

Dec 30, 2022

A modern, fast and scalable websocket framework with elegant API written in Go

A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Jan 4, 2023

WebSocket Connection Smuggler

WebSocket Connection Smuggler

ws-smuggler ws-smuggler is websocket connection smuggling testing tool. It is similar to the this project, but it has been rewritten based on the web

Jan 3, 2023

This package helps establish a websocket connection to the bilibili streaming server.

biliStreamClient This package helps establish a websocket connection to the bilibili streaming server. bilibili直播弹幕的WebSocket协议分析请参考:https://blog.csdn

Oct 25, 2022
TCP over HTTP/WebSocket

Introduction toh is tcp over http. short words: proxy your network over websocket Table of contents ToH server Caddy or Nginx wrap ToH server with TLS

May 6, 2023
TcpRoute , TCP 层的路由器。对于 TCP 连接自动从多个线路(电信、联通、移动)、多个域名解析结果中选择最优线路。

TcpRoute2 TcpRoute , TCP 层的路由器。对于 TCP 连接自动从多个线路(允许任意嵌套)、多个域名解析结果中选择最优线路。 TcpRoute 使用激进的选路策略,对 DNS 解析获得的多个IP同时尝试连接,同时使用多个线路进行连接,最终使用最快建立的连接。支持 TcpRoute

Dec 27, 2022
Multiplexer over TCP. Useful if target server only allows you to create limited tcp connections concurrently.

tcp-multiplexer Use it in front of target server and let your client programs connect it, if target server only allows you to create limited tcp conne

May 27, 2021
TCP output for beats to send events over TCP socket.

beats-tcp-output How To Use Clone this project to elastic/beats/libbeat/output/ Modify elastic/beats/libbeat/publisher/includes/includes.go : // add i

Aug 25, 2022
Tcp chat go - Create tcp chat in golang

TCP chat in GO libs Go net package and goroutines and channels tcp tcp or transm

Feb 5, 2022
HTTP, HTTP2, HTTPS, Websocket debugging proxy
HTTP, HTTP2, HTTPS, Websocket debugging proxy

English | 简体中文 We recommend updating whistle and Node to ensure that you receive important features, bugfixes and performance improvements. Some versi

Dec 31, 2022
NotifyTool - A message forwarding service for http to websocket

notifyTool this is a message forwarding service for http to websocket task webso

Jan 3, 2022
PlanB: a HTTP and websocket proxy backed by Redis and inspired by Hipache.

PlanB: a distributed HTTP and websocket proxy What Is It? PlanB is a HTTP and websocket proxy backed by Redis and inspired by Hipache. It aims to be f

Mar 20, 2022
HTTP tunnel over Websocket
HTTP tunnel over Websocket

WS PROXY This is a reverse HTTP proxy over websockets. The aim is to securely make call to internal APIs from outside. How does it works a WSP client

Nov 12, 2022
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.

Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.

Jan 1, 2023