Przeglądaj źródła

add sample code

joe 4 lat temu
rodzic
commit
b3e064aa76

+ 12 - 0
sample/Makefile

@@ -0,0 +1,12 @@
+TCP=sample
+WS=wsd
+
+all: $(TCP)
+
+$(TCP): tcpws/echo_server.go tcpws/echo_protocol.go tcpws/echo_client.go
+	go build -o $(TCP) ./tcpws
+
+clean:
+	-rm $(TCP)
+
+.PHONY: all clean

+ 36 - 0
sample/README.md

@@ -0,0 +1,36 @@
+# Sample
+
+sample code for tcp&websocket
+
+## Usage
+
+### Compile
+
+```shell script
+# build
+$make
+# see usage
+$./sample
+```
+
+### Test TCP
+
+```shell script
+# first console window
+$./sample tcpserver
+
+# then open another console window
+$./sample tcpclient
+```
+
+### Test Websocket
+
+```shell script
+# first console window
+$./sample wsserver
+
+# then open another console window
+$./sample wsclient
+```
+
+Notice: TCP using the same port as Websocket server.

+ 113 - 0
sample/tcpws/echo_client.go

@@ -0,0 +1,113 @@
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"net/url"
+	"one.com/nnet"
+	"one.com/nnet/cpn"
+	"os"
+	"strings"
+	"time"
+)
+
+type ClientSessionCb struct {
+}
+
+func (self *ClientSessionCb) OnClosed(nnet.ISession, int32) {
+
+}
+
+func (self *ClientSessionCb) OnConnected(ses nnet.ISession) (bool, int32) {
+	return true, 0
+}
+
+func (self *ClientSessionCb) OnMessage(ses nnet.ISession, packet nnet.IPacket) bool {
+	p, ok := packet.(*EchoPacket)
+	if !ok {
+		return false
+	}
+	fmt.Fprintf(os.Stdout, "echo from server: id<%v>, msg<%v>\n", p.Id, p.Msg)
+	// dispatch(ses, p)
+	return true
+}
+
+func (self *ClientSessionCb) OnHeartbeat(ses nnet.ISession) bool {
+	p := &EchoPacket{
+		Id:  2,
+		Msg: "heartbeat",
+	}
+	_ = ses.AWrite(p, time.Second)
+	return true
+}
+
+func start_tcp_client() {
+	clt := cpn.NewTcpClient(&nnet.DefHubConfig, &ClientSessionCb{}, &TcpProtocol{})
+	err := clt.NewConnection(SERVER_ADDR, 5)
+	if err != nil {
+		panic(err)
+	}
+	reader := bufio.NewReader(os.Stdin)
+	fmt.Println("Type what you want to send to server:")
+	for {
+		fmt.Print("->")
+		line, _ := reader.ReadString('\n')
+		line = strings.Replace(line, "\n", "", -1)
+
+		p := &EchoPacket{
+			Id:  1,
+			Msg: line,
+		}
+		ses, err := clt.GetSession(5)
+		if err == nil {
+			err = ses.AWrite(p, time.Second*3)
+			if err != nil {
+				fmt.Println("ERROR:", err)
+				continue
+			}
+		}
+		if line == "quit" || line == "q" {
+			break
+		}
+	} // for
+	clt.Stop()
+}
+
+func start_ws_client() {
+	clt := cpn.NewWsClient(&nnet.DefHubConfig, &ClientSessionCb{}, &WsProtocol{})
+	u := url.URL{
+		Scheme: "ws",
+		Host:SERVER_ADDR,
+		Path:WS_PATH,
+	}
+	err := clt.NewConnection(u.String(), 5)
+	if err != nil {
+		panic(err)
+	}
+	reader := bufio.NewReader(os.Stdin)
+	fmt.Println("Type what you want to send to server:")
+	for {
+		fmt.Print("->")
+		line, _ := reader.ReadString('\n')
+		line = strings.Replace(line, "\n", "", -1)
+
+		p := &EchoPacket{
+			Id:  1,
+			Msg: line,
+		}
+		ses, err := clt.GetSession(5)
+		if err == nil {
+			err = ses.AWrite(p, time.Second*3)
+			if err != nil {
+				fmt.Println("ERROR:", err)
+				continue
+			}
+		}else{
+			fmt.Println("not found session")
+		}
+		if line == "quit" || line == "q" {
+			break
+		}
+	} // for
+	clt.Stop()
+}

+ 100 - 0
sample/tcpws/echo_protocol.go

@@ -0,0 +1,100 @@
+package main
+
+import (
+	"encoding/binary"
+	"encoding/json"
+	"fmt"
+	"io"
+	"one.com/nnet"
+)
+
+type EchoPacket struct {
+	Id  int32
+	Msg string
+}
+
+func (self *EchoPacket) ShouldClose() (bool, int32) {
+	if self.Msg == "quit" {
+		return true, 8
+	}
+	return false, 0
+}
+
+type TcpProtocol struct {
+}
+
+func (self *TcpProtocol) ReadPacket(conn nnet.IConn) (nnet.IPacket, error) {
+	buf := make([]byte, 2048)
+	n, err := io.ReadFull(conn, buf[:4])
+	if err != nil {
+		fmt.Println("ERROR1:", err)
+		return nil, err
+	}
+	if n != 4 {
+		fmt.Println("ERROR2:", "n != 4")
+		return nil, nnet.ErrReadBlocking
+	}
+	pkt := &EchoPacket{}
+	dataLen := binary.LittleEndian.Uint32(buf[:4])
+	n, err = io.ReadFull(conn, buf[4:4 + dataLen])
+	if n != int(dataLen) {
+		fmt.Println("ERROR3:", "n != dataLen", n, "!=", dataLen)
+		return nil, nnet.ErrReadBlocking
+	}
+	pkt.Id = int32(binary.LittleEndian.Uint32(buf[4:8]))
+	pkt.Msg = string(buf[8:])
+
+	return pkt, nil
+}
+
+func (self *TcpProtocol) Serialize(packet nnet.IPacket) ([]byte, error) {
+	p, yes := packet.(*EchoPacket)
+	if !yes {
+		fmt.Println("ERROR5:", "!yes")
+		return nil, nnet.ErrReadBlocking // some error
+	}
+	buf := make([]byte, 2048)
+
+	dataLen := 4 + len(p.Msg)
+	binary.LittleEndian.PutUint32(buf, uint32(dataLen))
+	binary.LittleEndian.PutUint32(buf[4:], uint32(p.Id))
+	copy(buf[8:], []byte(p.Msg))
+	return buf[:8+len(p.Msg)], nil
+}
+
+type WsProtocol struct {
+}
+
+func (self *WsProtocol) ReadPacket(conn nnet.IConn) (nnet.IPacket, error) {
+	buf := make([]byte, 2048)
+	n, err := conn.Read(buf)
+	if err != nil {
+		fmt.Println("ERROR1:", err)
+		return nil, err
+	}
+	//TODO decrypt
+	//TODO uncompress
+	pkt := &EchoPacket{}
+	err = json.Unmarshal(buf[:n], pkt)
+	if err != nil {
+		fmt.Println("ERROR2:", err)
+		return nil, err
+	}
+	return pkt, nil
+}
+
+func (self *WsProtocol) Serialize(packet nnet.IPacket) ([]byte, error) {
+	p, yes := packet.(*EchoPacket)
+	if !yes {
+		fmt.Println("ERROR3:", yes)
+		return nil, nnet.ErrReadBlocking // some error
+	}
+	data, err := json.Marshal(p)
+	if err != nil {
+		fmt.Println("ERROR4:", err)
+		return nil, err
+	}
+	//TODO compress
+	//TODO encrypt
+	return data, nil
+}

+ 105 - 0
sample/tcpws/echo_server.go

@@ -0,0 +1,105 @@
+package main
+
+import (
+	"fmt"
+	"net"
+	"one.com/nnet"
+	"one.com/nnet/cpn"
+	"os"
+	"os/signal"
+	"syscall"
+	"time"
+)
+
+const (
+	SERVER_ADDR = "127.0.0.1:3200"
+	WS_PATH = "/echo"
+)
+
+type ServerSessionCb struct {
+}
+
+func (self *ServerSessionCb) OnClosed(ses nnet.ISession, reason int32) {
+	fmt.Println("client quit:", ses.GetRawConn().RemoteAddr())
+}
+
+func (self *ServerSessionCb) OnConnected(ses nnet.ISession) (bool, int32) {
+	fmt.Fprintf(os.Stdout, "connected:%v\n", ses.GetRawConn().RemoteAddr())
+	return true, 0
+}
+
+func (self *ServerSessionCb) OnMessage(ses nnet.ISession, pkt nnet.IPacket) bool {
+	p, ok := pkt.(*EchoPacket)
+	if !ok {
+		return false
+	}
+	_, _ = fmt.Fprintf(os.Stdout, "received[%v] id<%v>, msg<%v>\n", time.Now().Format("15:04:05"), p.Id, p.Msg)
+	_ = ses.AWrite(p, time.Second)
+	return true
+}
+
+func (self *ServerSessionCb) OnHeartbeat(ses nnet.ISession) bool {
+	return true
+}
+
+func start_tcp_server() {
+	listener, err := nnet.Listen(SERVER_ADDR)
+	if err != nil {
+		panic(err)
+	}
+	tcpListener, ok := listener.(*net.TCPListener)
+	if !ok {
+		panic("interface")
+	}
+	server := cpn.NewTcpServer(&nnet.DefHubConfig, &ServerSessionCb{}, &TcpProtocol{}, tcpListener)
+	go func() {
+		err = server.Start()
+		if err != nil {
+			panic(err)
+		}
+	}()
+	fmt.Println("tcp server started.")
+
+	ch := make(chan os.Signal)
+	signal.Notify(ch, syscall.SIGINT)
+
+	fmt.Println("received signal:", <-ch)
+	server.Stop()
+}
+
+func start_ws_server() {
+	server := cpn.NewWsServer(&nnet.DefHubConfig, &ServerSessionCb{}, &WsProtocol{}, SERVER_ADDR, WS_PATH, nil)
+
+	go func() {
+		err := server.Start()
+		if err != nil {
+			panic(err)
+		}
+	}()
+	fmt.Println("ws server started.")
+
+	ch := make(chan os.Signal)
+	signal.Notify(ch, syscall.SIGINT)
+
+	fmt.Println("received signal:", <-ch)
+	server.Stop()
+}
+
+func main() {
+	param := "tcpserver"
+	if len(os.Args) > 1 {
+		param = os.Args[1]
+	}
+	switch param {
+	case "tcpserver":
+		start_tcp_server()
+	case "tcpclient":
+		start_tcp_client()
+	case "wsserver":
+		start_ws_server()
+	case "wsclient":
+		start_ws_client()
+	default:
+		fmt.Fprintf(os.Stderr, "usage:%v [tcpserver|tcpclient|wsserver|wsclient]\n", os.Args[0])
+	}
+}