基於Go語言的命令行即時聊天工具——StormChat
簡介
前段時間心血來潮想學習最近的明星編程語言Golang。於是想做個聊天小程序實踐一下。程序基於TCP協議通信,更詳細的設計見設計思路。
用Golang實現了服務端程序,同時代碼抄抄改改做了個Golang客戶端,又由於輸出問題,用C++寫了個Windows控制臺的簡陋的輸出控制庫,於是客戶端在Windows上能看了(不過朋友說很醜>_<)。
在朋友(@Billows)的鼓勵下,我們決定用C#寫一個客戶端程序,正好他在學習WPF編程,於是界面採用了WPF編寫。我負責後臺數據交互,他負責前臺界面邏輯。
C#客戶端還使用到了JSON格式化庫Newtonsoft.Json,特此說明。
github地址:https://github.com/mattuylee/stormchat
設計思路
通信流程
- 發送方(客戶端或者服務器)發送數據包;
- 接收方(服務器或者客戶端)處理數據;
- 如果需要反饋,接收方發送反饋數據包;
- 發送方處理反饋數據(如果有)。
通信數據包結構
數據通信基於TCP協議,每次通信的數據包應包含【包頭域+數據域】。包頭域總是JSON格式、UTF-8編碼的字符串,數據域由包頭決定,可以為空。通信數據包結構如圖。

HEAD(包頭域)至少包含兩個參數:
- Toekn
- Operation
Token參數是一次通信的標識文本,由請求方隨機生成,處理方返回數據包的Token參數應和請求方的Token參數一致(如果有返回數據)。
Operation參數指定本次通信的請求。它決定了數據包的其他數據。Operation具體行為定義見這裡。
本來做了設計圖表,不過第一次用starUML,畫了一半才發現完全是鬼畫桃符,沒有掌握正確的作圖方式,也沒什麼熱情重新畫了。因此這裡不展示完整的設計文件了(本來也不完整),上面的鏈接是截取的關鍵部分(才知道starUML可以導出html文檔)。
哦,還有服務器端的數據庫結構,見文件stormchat-server/res/stormchat.sql。
環境配置
-
開發環境
服務器端:Windows/Linux Golang 1.11
客戶端-Go:Windows x64,C++,Golang 1.11
客戶端-C#:Windows,.NET4.0,WPF,Newtonsoft.Json for .NET4.0
-
運行環境
服務器端:Linux/Windows, MySQL5.5+/MariaDB10.0+
客戶端:Windows10 x64(其他平臺沒測試過)
程序配置
由於懶癌發作,一些參數設置只能在編譯時指定好,沒有運行中指定參數的功能。
Go語言的部分(服務器程序和golang客戶端程序)這塊都在control.go文件中,C#客戶端這邊也沒什麼可配置的,也就是連接服務器的地址和端口。下面列出部分配置參數:
服務器端
-
serveMode
服務(後臺)模式。如果此參數為true,日志輸出到str_log_file參數指定的文件中,且Debug()函數將不輸出內容。如果為false,日志輸出和Debug()函數都將直接向控制臺或終端輸出。 -
max_head_length
最大包頭長度,單位字節,如果包頭長度超過此參數將被拋棄。 -
max_message_length
最大消息長度,單位字節,如果消息長度超過此參數將被拋棄。 -
max_photo_size
最大頭像大小,單位字節,如果頭像數據長度超過此參數將被拋棄。 -
timeout_message
客戶端連接最大數據等待時間,單位秒。如果超過此時間客戶端沒有數據到達則斷開連接(此參數當前未啟用)。 -
str_log_file
日志文件。僅在serveMode為true時有效。注意,程序並不會自動清理此文件。 -
str_db_conn_str
MySQL數據庫連接字符串。
客戶端(Go)
- server_addr
服務器地址和端口。
客戶端(C#)
資源定義在StormChat解決方案,Interact項目的屬性->資源中。
-
RemoteServerAddr
服務器地址。 -
RemoteServerPort
服務器端口。
如何編譯
首先安裝git和golang,這一步請自行解決;
克隆項目到本地:
git clone -b master https://github.com/mattuylee/stormchat.git
假設項目已克隆到本地DIR目錄,命令行切換到stormchat目錄:
cd DIR/stormchat
-
服務器端
切換到服務器端工程目錄:
cd stormchat-server
克隆mysql操作庫
Go標準庫裡是沒有數據庫操作的庫的,因此先添加mysql操作庫到項目中。創建目錄sotormchat-server/src/github.com/go-sql-driver/,然後克隆MySQL操作庫:
cd src/github.com/go-sql-driver
git clone https://github.com/go-sql-driver/mysql.git
配置環境變量GOPATH
Windows下:
如果環境變量GOPATH存在,則在GOPATH後添加 ";DIR/stormchat/stormchat-server"(不含引號,注意分號),如果不存在添加GOPATH環境變量並將其設置為DIR/stormchat/stormchat-server即可,注意把DIR換成git倉庫所在目錄。
Linux下:
先查看GOPATH環境變量的值,再添加項目目錄到GOPATH:
echo $GOPATH
如果值為空:
export GOPATH=DIR/stormchat/stormchat-server
如果值不為空:
export GOPATH=$GOPATH:DIR/stormchat/stormchat-server
編譯程序
切換到stormchat-server/src/stormchat/目錄,然後編譯:
cd DIR/stormchat/stormchat-server/src/stormchat
go build
配置MySQL
登錄mysql:
mysql -uroot -p
為stormchat創建數據庫:
CREATE DATABASE stormchat CHARSET=UTF8;
導入數據庫結構:
SOURCE DIR/stormchat/stormchat-server/res/stormchat.sql;
創建用戶並授權:
CREATE USER 'stormchat'@'localhost' IDENTIFIED BY 'stormchat';
GRANT ALL ON stormchat.* TO 'stormchat'@'localhost';
FLUSH PRIVILEGES;
啟動服務器程序
Linux下執行下列命令以守護進程運行:
nohup ./stormchat &
Windows請自行探索。
-
客戶端-Go
cd DIR/stormchat/stormchat-client-golang/src
go build
注意,客戶端運行時需要conctrl_x64.dll在運行目錄下,此文件在stormchat-client-golang/res/目錄下。
-
客戶端-C#
Visual Studio 2015以上版本打開項目,直接編譯即可。
注意事項
- 沒有設計注冊賬戶的API,只能在強插數據庫。emmmm,這個坑懶得填了。
- 服務器端的日志文件不會自動清除(反正也沒什麼日志要寫)。
- 其他的,想到再補充。
目錄結構(主要部分)
stormchat │ .gitattributes │ .gitignore │ LICENSE //许可证 │ README.md //此帮助文件 │ ├─design //设计文件 │ message.png │ operations.svg │ stormchat.zip //starUML设计文件 │ │ ├─stormchat-server //服务器端工程目录 │ ├─res │ │ stormchat.sql //数据库结构 │ │ │ └─src //代码文件 │ └─stormchat │ control.go │ err.go │ main.go │ message.go │ session-deprecated.go //已不推荐使用的接口 │ session.go │ storm-server.go │ user.go │─stormchat-client-golang //Go客户端工程目录 │ ├─res │ │ conctrl_x64.dll //Winodws控制台输出库 │ │ icon.ico //客户端图标 │ │ │ └─src │ control.go //参数控制 │ main.go │ session.go │ stormchat-client.syso //资源文件(图标资源) │ user.go │ win-console.go //输出控制,调用conctrl库 │ └─stormchat-client-csharp //C#客户端工程目录 ├─Interact //数据交互模块 │ │ Interact.csproj //Visual Studio项目文件 │ │ Newtonsoft.Json.dll //JSON格式化库 │ │ AttrNames.cs //一些字符串常量 │ │ Client.cs //提供给数据表现模块的静态类 │ │ Client-Fields.cs //部分类,定义内部字段 │ │ Client-Handle.cs //部分类,处理服务器数据的方法 │ │ Client-Read.cs //部分类,接收服务器数据的方法 │ │ Client-Send.cs //部分类,向服务器发送数据的方法 │ │ Exception.cs │ │ jsonObject.cs //定义一些内部使用的结构,用于JSON格式化 │ │ Message.cs //定义一些数据结构,用于数据交换 │ │ User.cs //定义用户 │ │ │ └─Properties //项目属性和资源 │ AssemblyInfo.cs │ Resources.Designer.cs │ Resources.resx │ └─StormChatWPF //数据表现和用户交互模块*使用截圖
Golang客戶端

