客户端:
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)
}
}