1. 項(xiàng)目介紹
很多手機(jī)APP會(huì)不定時(shí)的給用戶推送消息,例如一些新聞APP會(huì)給用戶推送用戶可能感興趣的新聞,或者APP有更新了,會(huì)給用戶推送是否選擇更新的消息等等,這就是所謂的“消息推送”。此項(xiàng)目主要是基于SuperSocket的消息推送項(xiàng)目,打通了B/S(瀏覽器/服務(wù)器)與C/S(客戶端/服務(wù)器)的網(wǎng)絡(luò)通訊。
若有興趣學(xué)習(xí)此項(xiàng)目,請(qǐng)點(diǎn)擊項(xiàng)目下載地址進(jìn)行下載
在項(xiàng)目中
- 我們將
GA.SuperSocket.Service項(xiàng)目作為我們的Web服務(wù)站點(diǎn),在其站點(diǎn)下寄宿了Socket服務(wù),當(dāng)站點(diǎn)啟動(dòng)后,socket服務(wù)也會(huì)跟著啟動(dòng); -
GA.SuperSocket.AppClient是模仿的桌面程序(PC端),實(shí)現(xiàn)登錄并接收消息 -
GA.SuperSocket.MobileApp是模仿的移動(dòng)手機(jī)端(發(fā)送消息功能),對(duì)這個(gè)客戶端(發(fā)送消息)可以打開多次,相當(dāng)于有多部手機(jī),發(fā)送消息發(fā)給Socket服務(wù),由Socket服務(wù)轉(zhuǎn)發(fā)消息給指定的客戶端(PC端)接收消息.
項(xiàng)目截圖
-
多個(gè)客戶端與服務(wù)端的socket服務(wù)連接并給指定用戶發(fā)送消息
示例圖片1
示例圖片2 -
通過(guò)瀏覽器給指定用戶發(fā)送消息
示例圖片1
示例圖片2 -
發(fā)送離線消息給admin01
示例圖片1
示例圖片2
通信流程圖

實(shí)現(xiàn)功能如下:
- 實(shí)現(xiàn)模擬手機(jī)端對(duì)PC端的桌面程序發(fā)送消息,即客戶端之間形成網(wǎng)絡(luò)通訊進(jìn)行消息發(fā)送;
- 實(shí)現(xiàn)服務(wù)端發(fā)送消息給PC端的桌面程序;
- 實(shí)現(xiàn)客戶端掉線后由服務(wù)端發(fā)送消息后緩存到Redis作為離線消息,當(dāng)客戶端登錄上線后立馬收到消息;
- 實(shí)現(xiàn)客戶端斷線重連功能。
2. 知識(shí)覆蓋點(diǎn)
下面是項(xiàng)目所覆蓋的知識(shí)點(diǎn)介紹:
- C# Winform技術(shù),主要是實(shí)現(xiàn)客戶端的模擬;
- .net WebService基本使用技巧;
- .net開源SuperSocket實(shí)現(xiàn)服務(wù)端向指定客戶端推送消息;
- IIS程序發(fā)布與部署;
- TCP/IP端口號(hào)的問(wèn)題處理以及部署Redis(緩存數(shù)據(jù)庫(kù))的基本操作和使用;
- 為了防止網(wǎng)絡(luò)抖動(dòng)出現(xiàn)TCP假死連接,Socket客戶端與服務(wù)端互發(fā)心跳數(shù)據(jù)包,維持長(zhǎng)連接;
- 服務(wù)端崩潰或重啟站點(diǎn)后Socket客戶端實(shí)現(xiàn)自動(dòng)斷線重連;
- 防止IIS自動(dòng)回收應(yīng)用程序進(jìn)程的基本設(shè)置;
- Redis消息隊(duì)列存儲(chǔ)用戶離線數(shù)據(jù)實(shí)現(xiàn)消息的持久化。
學(xué)習(xí)建議:由于Socket屬于高級(jí)編程,覆蓋的知識(shí)點(diǎn)稍微比較多,建議至少擁有C# Winform以及.net mvc的基礎(chǔ)初學(xué)者可以學(xué)習(xí),否則不建議去學(xué)。
3. Socket通信基本流程圖

4. 框架及代碼解讀
服務(wù)端即部署的IIS站點(diǎn),PC端和移動(dòng)端均屬于不同平臺(tái)下的客戶端。
4.1. 服務(wù)端
4.1.1. 框架解讀

-
GA.SuperSocket.Service屬于Web應(yīng)用程序,.net framework 4.5版本
示例圖2 -
引用
示例圖3
- 序列化對(duì)象和日志組件庫(kù);
- redis以及socket核心組件庫(kù);
- 讀取Web.config的庫(kù)
- Core
屬于項(xiàng)目的核心程序,主要實(shí)現(xiàn)了服務(wù)端的socket監(jiān)控、發(fā)送心跳數(shù)據(jù)包維持長(zhǎng)連接、接收客戶端消息、發(fā)送消息、采用redis轉(zhuǎn)發(fā)離線消息等功能。 - Model
自定義的實(shí)體類 - Service
通過(guò)調(diào)用Core的核心方法對(duì)外提供接口 - Utility
輔助及擴(kuò)展類 -
AppServiceConfig.xml
xml配置文件,配置了redis的連接字符串
示例圖4
示例圖5 - FastPrintNetService.asmx
作為開放給客戶端的Web引用文件,主要是提供接口,默認(rèn)啟動(dòng)程序時(shí)在瀏覽器打開的文件。 - Global.asax
程序啟動(dòng)文件,初始化配置以及啟動(dòng)socket服務(wù)程序 - Packages.config
引用的包文件,包含了各個(gè)引用的文件包名、版本、.net framework版本 -
Web.config
主要是配置日志信息(日志組件庫(kù)、打印日志的輸出格式)以及socket監(jiān)聽端口
示例圖6
示例圖7
4.1.2. 初始化配置
-
Socket監(jiān)聽端口
示例圖7 -
啟動(dòng)文件配置
示例圖8
示例圖9 -
運(yùn)行時(shí)注意
示例圖10
示例圖11
4.1.3. 代碼解讀
- 文件名:
SuperSocketEnginePrintStrategy.cs是靜態(tài)文件,不需要new對(duì)象就可以直接使用其方法
a) 初始化socket服務(wù)
示例圖12
啟動(dòng)socket服務(wù)、監(jiān)聽會(huì)話連接、監(jiān)聽來(lái)自客戶端的消息發(fā)送、監(jiān)聽會(huì)話關(guān)閉會(huì)話連接:tcpServerEngine_NewSessionConnected,當(dāng)客戶端一旦上線后socket服務(wù)會(huì)自動(dòng)監(jiān)聽到連接請(qǐng)求并創(chuàng)建socket會(huì)話,即進(jìn)入到tcpServerEngine_NewSessionConnected方法里,即MyAppSession是客戶端請(qǐng)求連接時(shí)自動(dòng)創(chuàng)建的session數(shù)據(jù)

b) 定時(shí)向在線的客戶端發(fā)送心跳數(shù)據(jù)包
主要是為了維持與客戶端的長(zhǎng)連接,因?yàn)閠cp連接會(huì)因?yàn)榫W(wǎng)絡(luò)等原因出現(xiàn)斷連情況,如果斷連會(huì)導(dǎo)致服務(wù)端與客戶端無(wú)法通信,就好比手機(jī)的電話卡處于無(wú)服務(wù)狀態(tài),手機(jī)信號(hào)其實(shí)也是不斷地通過(guò)發(fā)送或接收數(shù)據(jù)維持電話信號(hào)的。具體請(qǐng)看流程圖3. socket通信基本流程圖。

c) 檢測(cè)登錄用戶上線后自動(dòng)打印離線消息發(fā)送給指定用戶

- 文件名:
RedisQueueMessageStrategy.cs
a) 初始化redis對(duì)象
示例圖16
示例圖17
b) 存儲(chǔ)離線消息
配合SuperSocketEnginePrintStrategy文件中的程序會(huì)通過(guò)這里的SendMessage方法發(fā)送消息過(guò)來(lái),用于存儲(chǔ)離線消息到redis中
示例圖17
c) 取出離線消息
配合SuperSocketEnginePrintStrategy文件中的程序檢測(cè)到用戶一旦上線后,會(huì)通過(guò)這里的ReceiveMessage方法從redis取出存儲(chǔ)的離線消息
示例圖18
4.2. PC端
4.2.1. 框架解讀

-
GA.SuperSocket.AppClient屬于Windows應(yīng)用程序,.net framework 4.5版本
示例圖20.png -
引用
示例圖20
- 序列化對(duì)象和日志組件庫(kù);
- socket核心組件庫(kù);
- 讀取App.config、Web.config的庫(kù)
-
Web References
引用服務(wù)端部接口,采用Web引用,如下圖所示:
示例圖21
示例圖22
示例圖23
示例圖24 -
Core
主要是用來(lái)加載配置文件AppServiceConfig.xml,獲取到遠(yuǎn)程web服務(wù)IP地址和Socket服務(wù)器IP地址及端 -
Model
自定義的實(shí)體類 -
Resources
放置Winform客戶端的一些圖標(biāo)資源 -
Utility
輔助及擴(kuò)展類 -
App.config
主要是配置日志信息(日志組件庫(kù)、打印日志的輸出格式)以及遠(yuǎn)程服務(wù)地址
示例圖25 -
AppServiceConfig.xml
示例圖26 -
LoginForm.cs
示例圖27 -
MessageMainForm.cs
示例圖28 -
MyTerminatorReceiveFilter.cs
將數(shù)據(jù)包的數(shù)據(jù)進(jìn)行轉(zhuǎn)化,轉(zhuǎn)化為StringPackageInfo類的格式。注意:發(fā)送數(shù)據(jù)時(shí)協(xié)議上規(guī)定必須以“/r/n”進(jìn)行結(jié)束。 -
Packages.config
引用的包文件,包含了各個(gè)引用的文件包名、版本、.net framework版本 -
Program.cs
程序啟動(dòng)類文件
4.2.2. 代碼解讀
- 文件名:
Program.cs是程序啟動(dòng)文件

程序啟動(dòng)后顯示登錄窗口,填寫用戶名、密碼登錄成功后進(jìn)入到消息窗口。
- 文件名:
MessageMainForm

核心程序就是:
初始化socket并綁定相關(guān)事件;
發(fā)起對(duì)socket服務(wù)的連接請(qǐng)求;
發(fā)送連接成功后的確認(rèn)信息給服務(wù)端

4.3. 移動(dòng)端
GA.SuperSocket.MobileApp此項(xiàng)目比較簡(jiǎn)單,主要是給在線的指定用戶發(fā)送消息。
5. Redis部署
下載redis,下載地址:https://redis.io/download


(1)打開命令窗口
本人的安裝路徑是
C:\\Program Files\Redis下,Shift +右鍵鼠標(biāo)操作,點(diǎn)擊“在此處打開命令窗口”,進(jìn)入到命令窗口。(2)啟動(dòng)服務(wù)命令
輸入下圖命令,如果出現(xiàn)下面的圖示即表示啟動(dòng)成功。
命令:
redis-server redis.windows.conf
(3)安裝服務(wù)
由于上面雖然啟動(dòng)了
redis服務(wù)命令,但是只要關(guān)閉cmd窗口,redis服務(wù)就會(huì)停止。所以要把redis設(shè)置成windows下的服務(wù)。命令:
redis-server --service-install redis.windows-service.conf --loglevel verbose
(4)啟動(dòng)服務(wù)
打開本機(jī)上的 任務(wù)管理器->服務(wù),找到Redis服務(wù)并啟動(dòng)即可。
注意:啟動(dòng)類型要設(shè)置為 自動(dòng),否則每次電腦開機(jī),此服務(wù)不會(huì)自動(dòng)啟動(dòng)。
Redis服務(wù)安裝時(shí)的報(bào)錯(cuò)問(wèn)題
如果出現(xiàn)下圖報(bào)錯(cuò),即表示該端口下的服務(wù)已被使用,則需要重新啟動(dòng)服務(wù)即可。

解決辦法:
按照上面的第(1)操作的命令窗口下按順序輸入三次命令:redis-cli.exe、shutdown、exit,然后進(jìn)入到上面的第(2)步操作

Redis操作命令學(xué)習(xí)地址:https://www.runoob.com/redis/redis-security.html
地址中包含了我們要給redis設(shè)置訪問(wèn)密碼的命令行,如下圖所示:

redis學(xué)習(xí)地址:https://www.cnblogs.com/weifeng1463/p/9713594.html
該地址包含了redis客戶端的下載https://pan.baidu.com/s/1QvjG30IV-MJFPTF-oV9nVw
以及客戶端連接redis的操作方法
6. 本地IIS發(fā)布流程
服務(wù)端發(fā)布


若我們配置的站點(diǎn)長(zhǎng)時(shí)間未被訪問(wèn)會(huì)被IIS自動(dòng)回收,防止IIS自動(dòng)回收應(yīng)用程序進(jìn)程的基本設(shè)置。



客戶端發(fā)布
































