[go] 聊天室服务器端四--MainServer

MainServer.go

// Package mainserver is main server
package mainserver

import (
	"GoWorkspace/go_line_chat/src/server/chatlog"
	"GoWorkspace/go_line_chat/src/server/configer"
	"GoWorkspace/go_line_chat/src/server/event"
	"GoWorkspace/go_line_chat/src/server/servers"
	"encoding/json"
	"fmt"
	"net"
)

// MainServer 主服务器结构体.
type MainServer struct {
	// 服务器端口号
	port int
	// 主服务监听指针。
	listener net.Listener
	// 事件工具
	eventFactory *event.EventFactory
}

// StartMainServer 静态函数,启动主服务器服务。
func StartMainServer(p int) *MainServer {
	var server = new(MainServer)
	// 设置端口。
	server.port = p
	//
	server.eventFactory = event.NewEventFactory()
	// 启动服务。
	server.Start()

	return server
}

func (mainServer *MainServer) log(msg string) {
	chatlog.Append(chatlog.LOGMAINSERVER, msg)
}

// Start 开始服务
func (mainServer *MainServer) Start() servers.ServerErrorType {
	mainServer.log(fmt.Sprintf("启动主服务器[端口: %d]\r\n", mainServer.port))
	var ip = ""
	ip = fmt.Sprintf("127.0.0.1:%d", mainServer.port)
	//1. 监听
	var err error
	mainServer.listener, err = net.Listen("tcp", ip)
	if err != nil {
		mainServer.log(fmt.Sprintf("net.Listen: %s", err))
		return servers.ServerErrorListen
	}

	// 启动监听
	go mainServer.startListen()

	return servers.ServerErrorNone
}

// Stop 停止服务
func (mainServer *MainServer) Stop() {
	mainServer.log("停止主服务器\r\n")
}

// Restart 重启服务
func (mainServer *MainServer) Restart() {
	mainServer.Stop()
	mainServer.Start()
}

// startListen 开启监听
func (mainServer *MainServer) startListen() {
	mainServer.log("主服务器开始监听\r\n")
	for {
		// 客户端连接。
		client, err := mainServer.listener.Accept()
		if err != nil {
			mainServer.log("conn fail ...")
		} else {
			mainServer.log(fmt.Sprintf("客户端连接: %s", client.RemoteAddr().String()))
			configer.ClientMap.Store("test", client)
			fmt.Printf("configer.ClientMap1: %v", configer.ClientMap)

			// 当客户连接时,启动一个线程,处理线程的消息。
			go mainServer.onClientConnect(client)
		}
	}
}

// onClientConnect 当有客户端链接时,处理。
func (mainServer *MainServer) onClientConnect(client net.Conn) {
	for {
		data := make([]byte, 1024)
		// 读取数据
		msgLength, err := client.Read(data)

		if msgLength == 0 || err != nil {
			mainServer.log(fmt.Sprintf("客户端断开: %s", client.RemoteAddr().String()))
			//
			mainServer.onClientDisConnect(client)
			return
		}

		//
		msg := string(data[0:msgLength])
		go mainServer.onReadClientData(client, msg)
	}
}

// 当客户端断开时。
func (mainServer *MainServer) onClientDisConnect(client net.Conn) {
	// 从ClientMap移除
	configer.ClientMap.Range(func(k, v interface{}) bool {
		fmt.Println("iterate:", k, v)
		if v == client {
			configer.ClientMap.Delete(k)
			return false
		}
		return true
	})
}

// 当读到客户端数据时。
func (mainServer *MainServer) onReadClientData(client net.Conn, msg string) {
	// json数据。
	var jsonReslut map[string]interface{}

	// 解析Json数据
	err := json.Unmarshal([]byte(msg), &jsonReslut)
	if err != nil {
		return
	}

	// 判断json数据是否合法
	var eventType = jsonReslut["type"]
	if eventType == nil {
		return
	}

	// 如果是合法的类型,则进入分发消息阶段。
	mainServer.eventFactory.Parse(jsonReslut, client)
}

用途:

  1. 创建TCP SERVER
  2. 当收到客户端数据时,将数据解析成json格式,判断其是否是我们定义的格式,如果是,则抛给eventFactory这个类去处理。
  3. 当客户断开时,我们应该把他的net.Conn从ClientMap中移除。

网上很多教程其实核心就是这个tcp server, 当客户连接了将net.Conn保存起来;发送消息也是直接跟其它的net.Conn通信。这种忒简单,学不到东西。俺们的是要带数据库的。慢慢来哈…

附上Conifger.go
很简单,目前就定义了两全局变量.

package configer

import "sync"

// 当前的日志模式
var CurrentLogMode int

// 所有登陆用户
// [string]tcp.Conn
// [用户名]clientConn
var ClientMap sync.Map

猜你喜欢

转载自blog.csdn.net/dkaily1314/article/details/89302428