ASP.NET SignalR 與LayIM配合,輕鬆實現網站客服聊天室(八)之 聊天記錄入隊(列)

丶Pz發表於2016-05-25

  本篇也算是個番外篇了,跟之前幾篇關係不算大。之前一篇  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而已。要學的東東還有很多,繼續努力。

相關文章