本篇也算是個番外篇了,跟之前幾篇關係不算大。之前一篇 RabbitMQ .NET Client 實戰實驗 裡有介紹過今天要用的內容。
做了一下小更改,就是在使用者聊天的時候,訊息記錄不直接進入資料庫,而是進入佇列。然後等待佇列逐條處理進入資料庫。佇列的好處就是確保每條都能得到正確處理,如果資料插入失敗,也不會出現資料丟失的情況。(很遺憾我自己還沒實現處理失敗的情況)
直接進入正題,先新建一個專案,引入相應的dll
ChatQueue程式碼:
public sealed class ChatQueue { /// <summary> /// 聊天訊息佇列名稱 /// </summary> const string QueueName = "LAYIM_CHAT_MSG_QUEUE"; /// <summary> /// 接收到佇列訊息,進行處理 /// </summary> public static void StartListeningChat() { IMessageCustomer customer = new MessageCustomer(QueueName); //開始訊息監聽 customer.StartListening(); //接收到訊息後的回撥 customer.ReceiveMessageCallback = message => { //反序列化訊息實體 var msgModel = JsonHelper.DeserializeObject<ChatMessageResult>(message); //呼叫方法插入資料庫(這裡沒判斷是否具體插入成功,只為測試,預設都按照成功處理) UserBLL.AddMessage(msgModel);
/*經過本人驗證,如果這裡返回false,佇列不會繼續處理下一條訊息,我目前的思路是,如果有一條出現了異常,那麼還是返回true,
不過將異常的訊息記錄日誌或者放入另一條佇列集中處理,防止影響下一條記錄的插入,正常情況下,如果出現一個問題,很有可能都是這個問題,
至於其他機制,目前正在研究中。。。
*/ return true; }; } /// <summary> /// 佇列訊息釋出 /// </summary> /// <param name="message"></param> public static void PublishMessage(ChatMessageResult message) { IMessageProduct product = new MessageProduct(QueueName); //將訊息序列化之後,釋出到佇列 var strMessage = JsonHelper.SerializeObject(message); product.Publish(strMessage); } }
然後在Startup檔案中開啟佇列監聽:
//開啟佇列監聽 ChatQueue.StartListeningChat();
最後在修改Hub中的程式碼:
var groupId = MessageHelper.GetGroupName(result.fromuser.id, result.touser.id); result.groupid = groupId; result.type = Config.Chat_One;//1v1 result.msgtype = MessageType.Custom;//聊天訊息,非系統訊息 result.status = 1; result.msgid = Guid.NewGuid().ToString(); //傳送給佇列 ChatQueue.PublishMessage(result); /* //如果沒有佇列的話,就將上邊的註釋掉然後切換到直接新增到資料庫 //UserBLL.AddMessage(result); */ //傳送給客戶端 return Clients.Group(groupId).receiveMessage(result);
還有,一定要記得配置好相應的佇列資訊:
<appSettings> <add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> <!--RabbitMQ--> <add key="RabbitMQ_HostUri" value="amqp://192.168.1.119:5672/"/> <add key="RabbitMQ_HostName" value="192.168.1.119"/> <add key="RabbitMQ_UserName" value="test_user"/> <add key="RabbitMQ_Password" value="123456"/> <add key="RabbitMQ_VirtualHost" value="ms_mq"/> </appSettings>
OK,直接執行一下跑跑吧。到這裡基本就把訊息經過佇列在插入資料庫實現了。當然,小小DEMO而已。要學的東東還有很多,繼續努力。