.net core 和 WPF 開發升訊威在線客服與營銷系統:使用 WebSocket 實現訪客端通訊

本系列文章詳細介紹使用 .net core 和 WPF 開發 升訊威在線客服與營銷系統 的過程。本產品已經成熟穩定並投入商用。
在線演示環境:https://kf.shengxunwei.com 注意:演示環境僅供演示交流與評估,不保證 7x24 小時可用。web

文章目錄列表請點擊這裏瀏覽器


對於在線客服與營銷系統,訪客端是指瀏覽網站的互聯網用戶,或是經過APP、微信等內嵌聊天頁面與後臺客服交流的用戶,在本篇文章中,我將詳細介紹如何在 .net core 環境下使用 WebSocket 技術實現訪客在網頁上與服務器進行通訊。服務器

這裏存在幾個技術難點須要注意:微信

  • 聊天界面要能無縫嵌入客戶的目標網站,對原網站不能有任何影響。
  • 訪客能夠經過網站右下角的浮動框,一邊聊天一邊瀏覽網站,網頁的跳轉、刷星都不能中斷聊天。
  • 須要考慮手機端聊天頁面鏈接不穩定的狀況,要能在APP或瀏覽器切到手機後臺失去鏈接時,對聊天狀態和信息進行保持。

訪客端實現的效果:app

訪客端在手機上的效果:框架

後臺客服的實現效果:asp.net


在 asp.net core 中配置中間件

首先咱們要在 Startup.cs 中,啓用 WebSocket 中間件:socket

var webSocketOptions = new WebSocketOptions() 
{
    KeepAliveInterval = TimeSpan.FromSeconds(120),
};

app.UseWebSockets(webSocketOptions);

可配置如下設置:async

  • KeepAliveInterval - 向客戶端發送「ping」幀的頻率,以確保代理保持鏈接處於打開狀態。 默認值爲 2 分鐘。
  • ReceiveBufferSize - 用於接收數據的緩衝區的大小。 高級用戶可能須要對其進行更改,以便根據數據大小調整性能。 默認值爲 4 KB。
  • AllowedOrigins - 用於 WebSocket 請求的容許的 Origin 標頭值列表。 默認狀況下,容許使用全部源。

接收訪客端的請求

在請求生命週期後期(例如在 Configure 方法或操做方法的後期),檢查它是不是 WebSocket 請求並接受 WebSocket 請求。性能

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            using (WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync())
            {
                await Echo(context, webSocket);
            }
        }
        else
        {
            context.Response.StatusCode = 400;
        }
    }
    else
    {
        await next();
    }

});

在請求期間對 Task 執行 await,以下面的示例所示:

app.Use(async (context, next) =>
{
    using (WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync())
    {
        var socketFinishedTcs = new TaskCompletionSource<object>();

        BackgroundSocketProcessor.AddSocket(webSocket, socketFinishedTcs);

        await socketFinishedTcs.Task;
    }
});

若是從操做方法返回過快,則還可能發生 WebSocket 關閉異常。 接受操做方法中的套接字時,須要用該套接字的代碼完成運行,而後再從操做方法返回。

收發訪客端消息

AcceptWebSocketAsync 方法將 TCP 鏈接升級到 WebSocket 鏈接,並提供 WebSocket 對象。 使用 WebSocket 對象發送和接收消息。
以前顯示的接受 WebSocket 請求的代碼將 WebSocket 對象傳遞給 Echo 方法。 代碼接收消息並當即發回相同的消息。 循環發送和接收消息,直到客戶端關閉鏈接:

private async Task Echo(HttpContext context, WebSocket webSocket)
{
    var buffer = new byte[1024 * 4];
    WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    while (!result.CloseStatus.HasValue)
    {
        await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);

        result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    }
    await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}

若是在開始循環以前接受 WebSocket 鏈接,中間件管道會結束。 關閉套接字後,管道展開。 即接受 WebSocket 時,請求中止在管道中推動。 循環結束且套接字關閉時,請求繼續回到管道。

處理訪客端鏈接斷開

訪客端因爲失去鏈接而斷開鏈接時,不會自動向服務器發送通知。 服務器只有在客戶端發送通知時纔會收到斷開鏈接消息。
若是客戶端並不是老是發送消息且不但願僅因爲鏈接進入空閒狀態就設置超時,則讓客戶端使用一個計時器並每隔多少秒發送一條心跳消息。 在服務器上,若是某條消息在上一條消息發出後的多少秒內還沒有到達,則終止鏈接並報告客戶端已斷開鏈接。


本文對使用 WebSocket 搭建訪客端通訊框架進行了簡要的介紹,在接下來的文章中,我將具體解構服務端程序的結構和設計、客服端程序的結構和設計,敬請關注。


在線演示環境:https://kf.shengxunwei.com 注意:演示環境僅供演示交流與評估,不保證 7x24 小時可用。

聯繫QQ: 279060597

推薦您關注個人微信訂閱號,在我更新文章或產品信息時會進行推送。

相關文章
相關標籤/搜索