這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
用戶端:
package main
import (
"context"
"errors"
"fmt"
"net"
"time"
"github.com/leesper/holmes"
"github.com/leesper/tao"
"github.com/leesper/tao/examples/echo"
)
//類比資訊的結構體
type SimulatorMessage struct {
Message []byte
}
var (
ErrorNilData error = errors.New("Nil data")
simulatorMessage SimulatorMessage
)
//初始化方法
func init() {
simulatorData := []byte{0x40, 0x40, 0x40, 0x42, 0x31, 0x36, 0x42, 0x30,
0x31, 0x41, 0x30, 0x30, 0x31, 0x58, 0x30, 0x30, 0x31, 0x5A, 0x10, 0x02,
0x51, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x64, 0x00, 0x00, 0x10,
0x03, 0x4F, 0xDF, 0x00, 0x00, 0x23, 0x23, 0x23}
//simulatorData = append(simulatorData, 0x44, 0x40, 0x40, 0x42, 0x31)
simulatorMessage = SimulatorMessage{Message: simulatorData}
}
func main() {
//預設開始和停止放到最前面
defer holmes.Start().Stop()
//tao架構註冊訊息(類比資訊的數量、還原序列化輸出資訊、過程資訊處理)
tao.Register(SimulatorMessage{}.MessageNumber(), DeserializeEchoMessage, ProcessPingPongMessage)
//撥號
c, err := net.Dial("tcp", "127.0.0.1:18341")
if err != nil {
//列印致命的日誌和退出。
holmes.Fatalln(err)
}
//返回服務端選項將設定回調時調用新的用戶端串連。
onConnect := tao.OnConnectOption(func(conn tao.WriteCloser) bool {
holmes.Infoln("on connect")
return true
})
//返回服務端選項將設定回調調用時出錯發生。
onError := tao.OnErrorOption(func(conn tao.WriteCloser) {
holmes.Infoln("on error")
})
//返回服務端選項將設定回調時要調用的用戶端關閉。
onClose := tao.OnCloseOption(func(conn tao.WriteCloser) {
holmes.Infoln("on close")
})
//返回服務端選項將設定回調時調用新的訊息到達。
onMessage := tao.OnMessageOption(func(msg tao.Message, conn tao.WriteCloser) {
echo := msg.(echo.Message)
fmt.Printf("%s\n", echo.Content)
})
//用戶端返回一個新的用戶端串連並沒有開始服務要求。
conn := tao.NewClientConn(0, c, onConnect, onError, onClose, onMessage)
conn.Start()
for i := 0; i < 100; i++ {
fmt.Printf("simulatorMessage %v \n", simulatorMessage)
time.Sleep(600 * time.Millisecond)
err := conn.Write(simulatorMessage)
if err != nil {
holmes.Errorln("%v", err)
}
}
time.Sleep(time.Second)
conn.Close()
}
//類比資訊序列化
func (em SimulatorMessage) Serialize() ([]byte, error) {
return em.Message, nil
}
//類比資訊數量
func (em SimulatorMessage) MessageNumber() int32 {
return 1
}
//過程資訊處理
func ProcessPingPongMessage(ctx context.Context, conn tao.WriteCloser) {
// rsp := ctx.Message().(pingpong.PingPongMessage)
// rspChan<- rsp.Info
// fmt.Printf("ctx : %v \n", ctx.Message())
}
//還原序列化輸出資訊
func DeserializeEchoMessage(data []byte) (message tao.Message, err error) {
if data == nil {
return nil, ErrorNilData
}
msg := SimulatorMessage{
Message: data,
}
fmt.Printf("接收服務端資料 : %v \n", data)
return msg, nil
}
服務端:
package main
import (
"fmt"
"net"
"os"
"os/signal"
"runtime"
"syscall"
"DeviceManagement-Service/common/setting"
"DeviceManagement-Service/device"
"DeviceManagement-Service/projectInit"
log "github.com/cihub/seelog"
"github.com/leesper/holmes"
"github.com/leesper/tao"
)
//定義一個資料庫變數
var (
serverConf *setting.ServerCfg
)
//驅動服務的結構體
type DeviceServer struct {
*tao.Server
}
//服務端初始化方法
func init() {
//項目初始化的log日誌
projectInit.Logger()
//擷取伺服器的設定檔資訊
serverConf, _ = projectInit.GetServerConf()
}
//返回一個新的裝置服務
func NewDeviceServer() *DeviceServer {
//返回服務端選項將設定回調時調用新的用戶端串連。
onConnectOption := tao.OnConnectOption(func(conn tao.WriteCloser) bool {
holmes.Infoln("on connect")
return true
})
//返回服務端選項將設定回調調用時出錯發生。
onErrorOption := tao.OnErrorOption(func(conn tao.WriteCloser) {
holmes.Infoln("on error")
})
//返回服務端選項將設定回調時要調用的用戶端關閉。
onCloseOption := tao.OnCloseOption(func(conn tao.WriteCloser) {
holmes.Infoln("close chat client")
})
//服務端返回一個新的TCP伺服器沒有啟動為請求服務。
return &DeviceServer{
tao.NewServer(onConnectOption, onErrorOption, onCloseOption),
}
}
func main() {
log.Info("啟動上位機")
runtime.GOMAXPROCS(runtime.NumCPU())
//預設開始和停止放到最前面
defer holmes.Start().Stop()
// tao.MonitorOn(12345)
//tao架構註冊訊息(裝置資訊的數量、還原序列化輸出裝置資訊、過程裝置資訊處理)
tao.Register(device.DeviceMessage{}.MessageNumber(), device.DeserializeDeviceMessage, device.ProcessDeviceMessage)
//tao.Register(device.DEVICE_MESSAGE, device.ProcessDeviceMessage)
//監聽連接埠
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", "0.0.0.0", serverConf.Port))
if err != nil {
holmes.Fatalln("listen error", err)
}
deviceServer := NewDeviceServer()
go func() {
c := make(chan os.Signal, 1)//有緩衝通道signal訊號量
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)//訊號通知
<-c
deviceServer.Stop()
}()
err = deviceServer.Start(l)
if err != nil {
//列印致命的日誌和退出。
holmes.Fatalln("start error", err)
}
}