跳到主要內容

基於Go語言的命令行即時聊天工具——StormChat

· 閱讀需 8 分鍾

簡介

  前段時間心血來潮想學習最近的明星編程語言Golang。於是想做個聊天小程序實踐一下。程序基於TCP協議通信,更詳細的設計見設計思路

  用Golang實現了服務端程序,同時代碼抄抄改改做了個Golang客戶端,又由於輸出問題,用C++寫了個Windows控制臺的簡陋的輸出控制庫,於是客戶端在Windows上能看了(不過朋友說很醜>_<)。

  在朋友(@Billows)的鼓勵下,我們決定用C#寫一個客戶端程序,正好他在學習WPF編程,於是界面採用了WPF編寫。我負責後臺數據交互,他負責前臺界面邏輯。

  C#客戶端還使用到了JSON格式化庫Newtonsoft.Json,特此說明。

github地址:https://github.com/mattuylee/stormchat

設計思路

通信流程

  1. 發送方(客戶端或者服務器)發送數據包;
  2. 接收方(服務器或者客戶端)處理數據;
  3. 如果需要反饋,接收方發送反饋數據包;
  4. 發送方處理反饋數據(如果有)。

通信數據包結構

數據通信基於TCP協議,每次通信的數據包應包含【包頭域+數據域】。包頭域總是JSON格式、UTF-8編碼的字符串,數據域由包頭決定,可以為空。通信數據包結構如圖。

stormchat通信規則

HEAD(包頭域)至少包含兩個參數:

  • Toekn
  • Operation

Token參數是一次通信的標識文本,由請求方隨機生成,處理方返回數據包的Token參數應和請求方的Token參數一致(如果有返回數據)。

Operation參數指定本次通信的請求。它決定了數據包的其他數據。Operation具體行為定義見這裡

本來做了設計圖表,不過第一次用starUML,畫了一半才發現完全是鬼畫桃符,沒有掌握正確的作圖方式,也沒什麼熱情重新畫了。因此這裡不展示完整的設計文件了(本來也不完整),上面的鏈接是截取的關鍵部分(才知道starUML可以導出html文檔)。

哦,還有服務器端的數據庫結構,見文件stormchat-server/res/stormchat.sql

環境配置

  1. 開發環境

    服務器端:Windows/Linux Golang 1.11
    客戶端-Go:Windows x64,C++,Golang 1.11
    客戶端-C#:Windows,.NET4.0,WPF,Newtonsoft.Json for .NET4.0

  1. 運行環境

    服務器端: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

  1. 服務器端

切換到服務器端工程目錄:

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請自行探索。

  1. 客戶端-Go

cd DIR/stormchat/stormchat-client-golang/src
go build

注意,客戶端運行時需要conctrl_x64.dll在運行目錄下,此文件在stormchat-client-golang/res/目錄下。

  1. 客戶端-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客戶端

stormchat使用截圖
stormchat使用截圖

源代碼

github地址:https://github.com/mattuylee/stormchat