Skip to content

06 Zinx Websocket | Kcp

刘丹冰 edited this page Jul 21, 2023 · 1 revision

Case Source Code : https://github.com/aceld/zinx-usage/tree/main/zinx_websocket

zinx.json configuration is as follows:

{
  "Name": "zinx v-0.10 demoApp",
  "Host": "127.0.0.1",
  "KcpPort": 7777,
  "MaxConn": 3,
  "WorkerPoolSize": 10,
  "LogDir": "./mylog",
  "LogFile": "zinx.log",
  "Mode": "websocket"
}

Mode:

  • "tcp": TCP listening,
  • "websocket": WebSocket listening,
  • "kcp": KCP listening,
  • Empty: Enable all modes simultaneously.

1. Server Service

The core code to upgrade net.conn to websocket in Go is as follows:

func (s *Server) ListenWebsocketConn() {
	var cID uint64
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if s.ConnMgr.Len() >= zconf.GlobalObject.MaxConn {
			zlog.Ins().InfoF("Exceeded the maxConnNum:%d, Wait:%d", zconf.GlobalObject.MaxConn, AcceptDelay.duration)
			AcceptDelay.Delay()
			return
		}
		conn, err := s.upgrader.Upgrade(w, r, nil)
		if err != nil {
			zlog.Ins().ErrorF("new websocket err:%v", err)
			w.WriteHeader(500)
			AcceptDelay.Delay()
			return
		}
		wsConn := newWebsocketConn(s, conn, cID)
		s.StartConn(wsConn)
		cID++
	})

	err := http.ListenAndServe(fmt.Sprintf("%s:%d", s.IP, s.WsPort), nil)
	if err != nil {
		panic(err)
	}
}

2. Starting the Server

There is a "Mode" field in the configuration file which controls whether to start the TCP server, the WebSocket server, or both. By default, only the TCP server is started. The mode can be changed to "websocket" or left empty to enable both.

package main

import (
	"github.com/aceld/zinx/examples/zinx_server/s_router"
	"github.com/aceld/zinx/znet"
)

func main() {
	// create a server handle
	s := znet.NewServer()

	// configure router
	s.AddRouter(100, &s_router.PingRouter{})
	s.AddRouter(1, &s_router.HelloZinxRouter{})

	// start the server
	s.Serve()
}

3. Starting the Client

Create a WebSocket client and provide a code block for connecting.

package main

import (
	"fmt"
	"github.com/aceld/zinx/examples/zinx_client/c_router"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
	"os"
	"os/signal"
	"time"
)

type PositionClientRouter struct {
	znet.BaseRouter
}

func (this *PositionClientRouter) Handle(request ziface.IRequest) {

}

// custom client business
func business(conn ziface.IConnection) {

	for {
		err := conn.SendMsg(1, []byte("ping ping ping ..."))
		if err != nil {
			fmt.Println(err)

		}
		time.Sleep(1 * time.Second)
	}
}

// executed when the connection is created
func DoClientConnectedBegin(conn ziface.IConnection) {
	// set two connection properties after the connection is created
	conn.SetProperty("Name", "Liu Danbing")
	conn.SetProperty("Home", "https://yuque.com/aceld")

	go business(conn)
}

func wait() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
}

func main() {
	// create a client handle using Zinx API
	client := znet.NewWsClient("127.0.0.1", 9000)

	// add business to be executed when the connection is established
	client.SetOnConnStart(DoClientConnectedBegin)
	// register server message router
	client.AddRouter(2, &c_router.PingRouter{})
	client.AddRouter(3, &c_router.HelloRouter{})

	// start the client
	client.Start()

	// close
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	sig := <-c
	fmt.Println("===exit===", sig)
	// clean up the client
	client.Stop()
	time.Sleep(time.Second * 2)
}
Clone this wiki locally