[go-tcpcat] Go TCP サーバー フレームワークはフック、関数コード関数をサポートします

Github ウェアハウス:https://github.com/xuehu96/go-tcpcat (Welcome Star)
国内ウェアハウス:https://gitee.com/xuehu96/go-tcpcat

TCP は IoT データ サーバーやゲーム サーバーなどでよく使用され、通常は独自形式のプロトコルです。go
-tcpcat は、非常に少ないコードで TCP の透過的な送信とメッセージ処理機能を実現できます。
メッセージ処理は Go 言語をサポートしています。プライベート プロトコルを転送するためのフックです。パーサーインジェクションフレームワーク、Luaスクリプト処理、PythonGRPC呼び出し処理、HTTPコールバック処理、Redisキャッシュデータなど

インストール:

go get -u github.com/xuehu96/go-tcpcat

1. フック

ドッグ関数はコールバック関数です。指定されたイベントが発生した後、フレームワークは事前に挿入された処理関数をコールバックします。デフォルト
の処理関数はログを通じて出力します。ドッグ関数を設定すると、デフォルトの処理関数がオーバーライドされます。

プログラムは次のドッグサブ関数を設定します。

通話のタイミング 使用例
オンリッスン リッスンが成功した後のコールバック プログラムの開始 新しいリソース
受け入れない 新しいクライアント接続呼び出し クライアントのソースを決定し、クライアントの数を制限する
OnReadData クライアントデータ呼び出しを受信しました データ形式を決定し、先頭と末尾を削除します。
OnFnCode データから関数コードを解析する ファンクションコードとカスタムファンクション処理関数
データ送信時 クライアントにデータを送信した後に呼び出されます 送信が成功したかどうかを判断し、再送信するか、発信者に通知します。
閉じる時 クライアントの開始後または切断後に呼び出されます 切断後にクライアントに通知またはオフラインのマークを付ける
オンストップ Listen が閉じられた後に呼び出されます リソースをクリーンアップする

犬の使い方:

var fnc1 server.OnXXXXXX = func(param) ret{
    
     
	// TODO
}
var fnc2 server.OnYYYYYY = func(param) ret{
    
    
	// TODO
}
         ...

hooks := server.Hook{
    
    
	OnXXXXXX: fnc,
	OnYYYYYY: fnc,
	...
}
s := server.New(
    server.WithHook(hooks),
	...
)

2. ファンクションコードとカスタムファンクション処理関数

HTTPルーティングと同様に、プライベートプロトコルにおけるデータパケットの処理方法を区別する機能コードを一般にファンクションコードと呼びます。

ファンクションコード解析機能OnFnCode(データからファンクションコードを解析)

var fnc server.OnFnCode = func(buf []byte) string {
    
    
	s := string(buf)
	if strings.Contains(s, "ping") {
    
    
		return "A"
	}
	if s[0] == 'B' {
    
    
		return "B"
	}
	return ""
}

hooks := server.Hook{
    
    
	OnFnCode: fnc,
}

対応する関数コードを処理する関数(ルーティングと同様)

s.AddFn("A", func(c *server.Client, code string, buf []byte, len int) {
    
    
	// TODO
})
s.AddFn("B", func(c *server.Client, code string, buf []byte, len int) {
    
    
    // TODO
})

3. ピンポン TCP サーバーの例

クライアントは接続後、データをサーバーに送信し、サーバーは次の形式でデータを処理します。

  • 「ピン」は「ポン」と答えます
  • 「time」は現在のサーバー時間を返します
  • 「exit」サーバーはアクティブに切断されました
  • クライアントが応答せずに他の形式を送信する
package main

import (
	"context"
	"github.com/xuehu96/go-tcpcat/pkg/logger"
	"github.com/xuehu96/go-tcpcat/server"
	"log"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)


func main() {
    
    
	// 创建TCPListener
	ln, err := net.Listen("tcp", ":9677")
	if err != nil {
    
    
		log.Fatalln(err.Error())
		return
	}

	// 自定义如何从数据包中获取获取功能码
	var fnc server.OnFnCode = func(buf []byte) string {
    
    
		s := string(buf)
		if strings.Contains(s, "ping") {
    
    
			return "p"
		}
		if strings.Contains(s, "time") {
    
    
			return "t"
		}
		if strings.Contains(s, "exit") {
    
    
			return "x"
		}
		return ""
	}

	hooks := server.Hook{
    
    
		OnFnCode: fnc,
	}
	// 创建TCP服务实例
	s := server.New(
		server.WithHook(hooks),
		server.WithListener(ln),
		server.WithLogger(logger.DebugLogger()),
	)

	// 添加功能码对应的处理函数 类似于HTTP的路由
	s.AddFn("p", func(c *server.Client, code string, data []byte) {
    
    
		c.ReplyData([]byte("pong"))
	})
	s.AddFn("t", func(c *server.Client, code string, data []byte) {
    
    
		currentTime := time.Now()
		c.ReplyData([]byte(currentTime.Format("2006-01-02 15:04:05.000000000")))
	})
	s.AddFn("x", func(c *server.Client, code string, data []byte) {
    
    
		c.Close()
	})

	// Ctrl-C 结束
	go func() {
    
    
		signalCh := make(chan os.Signal, 1)
		signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
		<-signalCh
		s.Stop(context.Background())
	}()

	// TCP服务器开始干活
	s.Serve()
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/xuehu96/article/details/126855943