Skip to content

Latest commit

 

History

History
163 lines (134 loc) · 5.35 KB

doc.md

File metadata and controls

163 lines (134 loc) · 5.35 KB

Go-socket Quick Start

Contents

Controller

While the go-socket server is listening to the target address and port, it can handle different requests by routing them to different controllers and actions. We can create controllers inherited from gosocket.Controller to handle requests made by the clients. Here is an example of ChatController in chat.go:

package main

import (
	"fmt"
	gosocket "github.com/yankawayu/go-socket"
	"strconv"
)

type ChatController struct {
	gosocket.Controller
}

type AddMessageReqBody struct {
	Message string `json:"message"`
}

func (controller *ChatController) GetActionParamMap() map[string]interface{} {
	return map[string]interface{}{
		"AddMessage": &AddMessageReqBody{},
	}
}

func (controller *ChatController) AddMessage(request *AddMessageReqBody, response *gosocket.ResponseBody) {
	fmt.Println("user " + strconv.FormatInt(controller.User.GetUid(), 10) + " message received: " + request.Message)
	response.Data = map[string]string{
		"message_id": "1",
	}
	response.Status = gosocket.StatusSuccess
}

In this class, the GetActionParamMap function is used to declare all the actions that can be handled by the controller. Then we add this ChatController to the router by inserting a new line to example.go:

package main

import (
	"github.com/yankawayu/go-socket"
)

func main() {
	appConfig := &gosocket.AppConfig{
		TcpAddr:   "0.0.0.0",
		TcpPort:   8080,
		TlsEnable: false,
	}
	fastLog := gosocket.GetFastLog("app.access", false)
	//Add ChatController to the router
	gosocket.Router("chat", &ChatController{})
	gosocket.Run(appConfig, nil, gosocket.GetLog(false), fastLog)
}

It is recommended that the router name chat is the same as the prefix of ChatController. Now we can access to the AddMessage action by using payload type chat.AddMessage in a client request.

If you want to run these two files in command line, you need to add chat.go to the file list:

go build example.go chat.go

Client

Go-socket has a built-in client. It's implemented by socket_client.go and socket_client_conn.go. Let's create a client.go that can be used to connect to the server we just created in the last section.

package main

import (
	"fmt"
	gosocket "github.com/yankawayu/go-socket"
)

func main() {
	client := gosocket.NewClient("127.0.0.1", 8080, false, gosocket.GetLog(false), nil)
	err := client.Connect()
	if err != nil {
		panic(err)
	}
	client.GetData("chat.AddMessage", map[string]string{
		"message": "This is a message",
	}, func(err error, data string) {
		fmt.Println("Content from server: "+data)
	}, []byte{})
	//Stop the client from exiting before the server responds
	forever := make(chan int)
	_ = <-forever
}

The client first connect to the server and then send a request on chat.AddMessage. If everything goes well, you will see the server response printed in the console:

{"message_id":"1"}

Auth

In the example above, there is no identification when the client connects to server. In fact, you can create a class that inherited from AuthUser to implement identification process as the following user.go:

package main

import (
	gosocket "github.com/yankawayu/go-socket"
	"github.com/yankawayu/go-socket/packet"
)

type TestUser struct {
	gosocket.AuthUser
}

func (user *TestUser) Auth(payload string, ip string) (uid int64, code packet.ReturnCode) {
	loginInfo := map[string]string{
		"username": "xxx",
		"password": "xxx",
	}
	gosocket.JSONDecode(payload, &loginInfo)
	uid = auth(loginInfo["username"], loginInfo["password"])
	return uid, packet.RetCodeAccepted
}

Please keep in mind that auth function is unimplemented. You should implement this function to perform the identification process. It is not recommended to use username and password in production environment design. Feel free to use any mechanism you want.

After you finish defining the auth class, use it to run the server like the following code:

gosocket.Run(appConfig, &TestUser{}, gosocket.GetLog(false), fastLog)

For the client, if you want to send the username and password, you need to create a class which implement GetConnectInfo function like the following:

package main

type ClientProvider struct{}

func (provider *ClientProvider) GetConnectInfo() string {
	return "{\"username\":\"haha\", \"password\":\"xxxxx\"}"
}

Then pass an instance of the provider to gosocket.NewClient function when you use it:

client := gosocket.NewClient("127.0.0.1", 8080, false, gosocket.GetLog(false), &ClientProvider{})

Error Handling

There is an interface IUserError for user defined error in error.go. Implement this interface in your custom error class to customize messages that responded to the client.

Log

There are two log utilities in the framework. One is called Log and another is called FastLog. The Log is used to log normal situations like error and critical since it's not efficient enough. While the FastLog can be used to log all the incoming requests or any other high frequent demands. Feel free to use them in your own situations.

Build an IM Server

The ultimate goal of this project is to support a high performance IM server developed by Go. I would like to release all related codes in the future. Hope it helps.