webim-plugin主要分為基于GatewayWorker開發的即時通訊組件和基于webserver開發的接口服務。
即時通訊組件主要用于和前端建立websocket連接,實現基于websocket的實時通信。
webserver主要用于提供im的相關html頁面及ajax接口。
## **GatewayWorker**
GatewayWorker基于Workerman開發的一個項目框架,用于快速開發TCP長連接應用,例如app推送服務端、即時IM服務端、游戲服務端、物聯網、智能家居等等
GatewayWorker使用經典的Gateway和Worker進程模型。Gateway進程負責維持客戶端連接,并轉發客戶端的數據給BusinessWorker進程處理,BusinessWorker進程負責處理實際的業務邏輯(默認調用Events.php處理業務),并將結果推送給對應的客戶端。Gateway服務和BusinessWorker服務可以分開部署在不同的服務器上,實現分布式集群。
GatewayWorker提供非常方便的API,可以全局廣播數據、可以向某個群體廣播數據、也可以向某個特定客戶端推送數據。配合Workerman的定時器,也可以定時推送數據。
## **webserver**
webserver是筆者為了本項目而開發的基于workerman-WebServer的輕量小型web框架,本框架主要特點就是小,只有控制器和view無繁瑣的model層和路由等。集成了web所需要的基本功能配置、文件上傳、調試模式、日志記錄、模板渲染輸出(基于smarty模板)、數據庫基本操作(集成的think-orm)。
# **原理**
了解系統原理前先了解下GatewayWorker工作原理
GatewayWorker主要包含Register、Gateway、BusinessWorker三個進程
1、Register、Gateway、BusinessWorker進程啟動
2、Gateway、BusinessWorker進程啟動后向Register服務進程發起長連接注冊自己
3、Register服務收到Gateway的注冊后,把所有Gateway的通訊地址保存在內存中
4、Register服務收到BusinessWorker的注冊后,把內存中所有的Gateway的通訊地址發給BusinessWorker
5、BusinessWorker進程得到所有的Gateway內部通訊地址后嘗試連接Gateway
6、如果運行過程中有新的Gateway服務注冊到Register(一般是分布式部署加機器),則將新的Gateway內部通訊地址列表將廣播給所有BusinessWorker,BusinessWorker收到后建立連接
7、如果有Gateway下線,則Register服務會收到通知,會將對應的內部通訊地址刪除,然后廣播新的內部通訊地址列表給所有BusinessWorker,BusinessWorker不再連接下線的Gateway
8、至此Gateway與BusinessWorker通過Register已經建立起長連接
9、客戶端的事件及數據全部由Gateway轉發給BusinessWorker處理,BusinessWorker默認調用Events.php中的onConnect onMessage onClose處理業務邏輯。
10、BusinessWorker的業務邏輯入口全部在Events.php中,包括onWorkerStart進程啟動事件(進程事件)、onConnect連接事件(客戶端事件)、onMessage消息事件(客戶端事件)、onClose連接關閉事件(客戶端事件)、onWorkerStop進程退出事件(進程事件)
Gateway/Worker 的進程模型

# **webim-plugin原理**
本系統在GatewayWorker基礎上多了一個webserver進程用于處理ajax接口和web頁面。所以本系統含有四個進程
1、Register進程用戶接收Gateway、BusinessWorker進程的注冊信息協助Gateway和BusinessWorker之間建立長連接
2、Gateway進程監聽websocket協議與客戶端建立長連接將用戶數據轉給BusinessWorker進程并負責將BusinessWorker進程的數據轉發給客戶端
3、BusinessWorker進程接收通過Gateway轉發來的數據,進行邏輯處理后再通過Gateway轉發給客戶端。
4、webserver監聽http協議用于提供web服務,主要做一些web網站處理和ajax接口。
各個進程之間都通過長連接通信,所有進程都可以分別部署在不同服務器上,并且Gateway和BusinessWorker服務器都可以增加多臺處理即時通訊邏輯。一般的分布式方案為遇到瓶頸時增加BusinessWorker服務器。Gateway進程只負責網絡IO一般不需要部署多臺(如有必要也可部署多臺,不過前端websocket地址需要自定義動態分發)。
### **數據庫方面**
webim-plugin用mysql存儲聊天信息redis存儲緩存信息和連接憑證token,對接已有網站時需要在已有網站暴露一個token接口,webim-plugin在建立socket連接前會請求此接口,此接口需要生成并在redis中按照要求寫入token信息,然后將token返回,webim-plugin會根據此token去對應用戶信息。