包体长度 |
命令号 |
扩展字段 |
包体 |
4字节 |
4字节 |
8字节 |
包体 |
- 包体长度,4字节,有最大长度限制,TcpServer/TcpEngine可以通过SetSockMaxPackLen设置最大包长
- 命令号,4字节,用户层协议最大命令号为0xFFFFFF,大于0xFFFFFF为net包保留协议号
心跳包协议号: CmdPing = uint32(0x1 << 24),无需包体
- 扩展字段,在rpc时为rpc call的序号标识
- 包体,用户可以自由选择序列化方案
package main
import (
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var ()
const (
addr = ":8888"
CMD_ECHO = uint32(1)
)
func onEcho(client *net.TcpClient, msg net.IMessage) {
log.Info("tcp server onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Body()))
client.SendMsg(msg)
}
func main() {
server := net.NewTcpServer("Echo")
// 初始化协议号
server.Handle(CMD_ECHO, onEcho)
server.Serve(addr, time.Second*5)
}
package main
import (
"fmt"
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var (
addr = "127.0.0.1:8888"
CMD_ECHO = uint32(1)
)
func onConnected(c *net.TcpClient) {
log.Info("TcpClient OnConnected")
}
func onEcho(client *net.TcpClient, msg net.IMessage) {
log.Debug("tcp client onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Body()))
}
func main() {
autoReconn := true
netengine := net.NewTcpEngine()
// 初始化协议号
netengine.Handle(CMD_ECHO, onEcho)
client, err := net.NewTcpClient(addr, netengine, nil, autoReconn, onConnected)
if err != nil {
log.Panic("NewTcpClient failed: %v, %v", client, err)
}
for i := 0; true; i++ {
err = client.SendMsg(net.NewMessage(CMD_ECHO, []byte(fmt.Sprintf("hello %v", i))))
if err != nil {
log.Error("tcp client echo failed: %v", err)
}
time.Sleep(time.Second)
}
}
package main
import (
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
)
var (
addr = ":8888"
CMD_ECHO = uint32(1)
)
func onEcho(client *net.WSClient, msg net.IMessage) {
log.Info("ws server onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Data()))
client.SendMsg(msg)
}
func main() {
server, err := net.NewWebsocketServer("echo", addr)
if err != nil {
log.Panic("NewWebsocketServer failed: %v", err)
}
// 初始化http ws路由
server.HandleWs("/ws/echo")
// 设置消息处理接口
server.HandleMessage(onEcho)
server.Serve()
}
package main
import (
"fmt"
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var (
addr = "ws://localhost:8888/ws/echo"
)
func onMessage(client *net.WSClient, msg net.IMessage) {
log.Debug("ws client onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Data()))
}
func main() {
client, err := net.NewWebsocketClient(addr)
if err != nil {
log.Panic("NewWebsocketClient failed: %v, %v", err, time.Now())
}
// 设置消息处理接口
client.HandleMessage(onMessage)
for i := 0; true; i++ {
err = client.SendMsg(net.RawMessage([]byte(fmt.Sprintf("hello %v", i))))
if err != nil {
log.Error("ws client echo failed: %v", err)
break
}
time.Sleep(time.Second)
}
}
package main
import (
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
)
var (
addr = ":8888"
CMD_ECHO = uint32(1)
)
func onEcho(client *net.WSClient, msg net.IMessage) {
log.Info("ws server onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Body()))
client.SendMsg(msg)
}
func main() {
server, err := net.NewWebsocketServer("echo", addr)
if err != nil {
log.Panic("NewWebsocketServer failed: %v", err)
}
// 初始化http ws路由
server.HandleWs("/ws/echo")
// 初始化协议号
server.Handle(CMD_ECHO, onEcho)
server.Serve()
}
package main
import (
"fmt"
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var (
addr = "ws://localhost:8888/ws/echo"
CMD_ECHO = uint32(1)
)
func onEcho(client *net.WSClient, msg net.IMessage) {
log.Debug("ws client onEcho from %v: %v", client.Conn.RemoteAddr().String(), string(msg.Body()))
}
func main() {
client, err := net.NewWebsocketClient(addr)
if err != nil {
log.Panic("NewWebsocketClient failed: %v, %v", err, time.Now())
}
// 初始化协议号
client.Handle(CMD_ECHO, onEcho)
for i := 0; true; i++ {
err = client.SendMsg(net.NewMessage(CMD_ECHO, []byte(fmt.Sprintf("hello %v", i))))
if err != nil {
log.Error("ws client echo failed: %v", err)
break
}
time.Sleep(time.Second)
}
}
package main
import (
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var (
addr = "0.0.0.0:8888"
)
type HelloRequest struct {
Message string
}
type HelloResponse struct {
Message string
}
// Hello方法
func Hello(ctx *net.RpcContext) {
req := &HelloRequest{}
err := ctx.Bind(req)
if err != nil {
log.Error("Hello failed: %v", err)
return
}
// 直接回包
// err = ctx.Write(&HelloResponse{Message: req.Message})
// if err != nil {
// log.Error("Hello failed: %v", err)
// return
// }
// log.Info("HelloRequest: %v", req.Message)
// 支持异步回包
go func() {
err = ctx.Write(&HelloResponse{Message: req.Message})
if err != nil {
log.Error("Hello failed: %v", err)
return
}
log.Info("HelloRequest: %v", req.Message)
}()
}
func main() {
server := net.NewRpcServer("Rpc")
// 初始化方法,类似http初始化路由
server.HandleRpcMethod("Hello", Hello)
// 启动服务
server.Serve(addr, time.Second*5)
}
package main
import (
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"time"
)
var (
addr = "0.0.0.0:8888"
)
type HelloRequest struct {
Message string
}
type HelloResponse struct {
Message string
}
func onConnected(c *net.RpcClient) {
log.Info("RpcClient OnConnected")
}
func main() {
engine := net.NewTcpEngine()
client, err := net.NewRpcClient(addr, engine, nil, onConnected)
if err != nil {
log.Panic("NewReqClient Error: %v", err)
}
for {
req := &HelloRequest{Message: "kiss"}
rsp := &HelloResponse{}
// 调用Hello方法
err = client.Call("Hello", req, rsp, time.Second*3)
if err != nil {
log.Error("Hello failed: %v", err)
} else {
log.Info("HelloResponse: %v", rsp.Message)
}
time.Sleep(time.Second)
}
}
- http只是简单支持优雅退出,实际路由等请使用标准库或其他第三方包
package main
import (
"github.com/gin-gonic/gin"
"github.com/nothollyhigh/kiss/log"
"github.com/nothollyhigh/kiss/net"
"net/http"
"time"
)
// http://localhost:8080/hello
func main() {
addr := ":8080"
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
router.GET("/hello", func(c *gin.Context) {
log.Info("onHello")
c.String(http.StatusOK, "hello")
})
net.ServeHttp("Hello", addr, router, time.Second*5, nil)
}