dotnet core 開發無縫相容Http和Websocket協議的介面服務

smark發表於2018-09-27

在應用介面開發中往往要針對不同協義開發相應的代理服務,但對於Websocket和http這兩種協議來說就有些不同,從實現上來看Websocket可以說是Http的升級子協議, 兩者在協議處理上基本一致,具體可以在解釋Body上有所不同。FastHttpApi在實現過程完全支援http協議升級成websocket協議,當制定一個基於http請求的介面時,其實已經是完全支援websocket協議;從而讓使用者只編寫一份程式碼即可同時接受兩種協議處理。接下來還是以Northwind的資料來描述FastHttpApi制定相應服務開發。

介面制定

對於FastHttpApi定義一個可訪問的Http介面是一件非常簡單的事情,和定義一個邏輯方法沒有多大的差異;以下是定義一個訂單查詢邏輯的http介面,返回Json格式的資料。

    [BeetleX.FastHttpApi.Controller]
    public class Controller 
    {
        public object GetEmployeesName()
        {
            return from e in mEmployees select new { ID = e.EmployeeID, Name = e.FirstName + " " + e.LastName };
        }
        public object GetCustomersName()
        {
            return from c in mCustomers select new { ID = c.CustomerID, Name = c.CompanyName };
        }
        public object ListOrders(int employeeid, string customerid, IHttpContext context)
        {
            return mOrders.Where(o =>
            (employeeid == 0 || o.EmployeeID == employeeid)
            &&
            (string.IsNullOrEmpty(customerid) || o.CustomerID == customerid));
        }
    }

以上程式碼定義了三個Http請求:

  1. /GetEmployeesName 獲取僱員的ID和名稱列表
  2. /GetCustomersName 獲取客戶的ID和名稱列表
  3. /ListOrders 查詢相應僱員和客戶的訂單資訊 在瀏覽器上直接訪問/GetEmployeesName的資料結果

 

FastHttpApi對介面響應有預設的Json格式返回,Code為HTTP返回的狀態碼,200為正常,如果不是200那會帶上Error資訊,Data則是具體響應的資料內容,Url則是對應請求的基礎地址。

頁面Ajax請求介面

既然通過瀏覽器訪問沒有問題,那接下來就可以通過Ajax進行資料請求了;以下是通過ajax呼叫/GetEmployeesName/GetCustomersName兩個方法。

        $.get("/GetEmployeesName", function (result) {
            a = result.Data;
            a.forEach(function (v, i) {
                $('#lstEmployees').append(' <option value="' + v.ID + '">' + v.Name + '</option>')
            });
        });
        $.get("/GetCustomersName", function (result) {
             a = result.Data;
            a.forEach(function (v, i) {
                $('#lstCustomers').append(' <option value="' + v.ID + '">' + v.Name + '</option>')
            });
        });

請求資料後繫結到select控制元件上,這種是相當原始的設定模式了,相信現有的web前端元件已經不需要這麼麻煩的工作了:)

訂單查詢

  function HttpSearch() {
        $.get('/listorders?employeeid=' + $('#lstEmployees').val() + "&customerid=" + $('#lstCustomers').val(), function (result) {
            bindOrders(result.Data);
        });
    }
  function bindOrders(items) {
        $("#lstbody").empty();
        items.forEach(function (v, i) {
            $("#lstbody").append('<tr><td>' + i + '</td><td>' + v.OrderID + '</td><td>' + v.ShipName + '</td><td>' + v.ShipAddress + '</td><td>' + v.ShipCity + '</td><td>' + v.OrderDate + '</td></tr>')
        });
    }

對於FastHttpApi制定方法引數的在http主要有兩種來源途徑,一種是通過Querystring提供,而另一種則通過Post一個json內容來提供;對於元件來說只要沒有新增[BodyParameter]標籤的引數都由QueryString來提供(實際使用中有特別的需要則可以實現自己Parameter的屬性標籤來擴充套件)。這樣一個訂單查詢的功能就開發完成了

 

WebSocket請求

由於服務埠和網站的埠是一致,所以構建websocket連線的時候並不要顯式地指定地址,直接拿瀏覽當前的Host地址即可。

  websocket = new WebSocket("ws://" + window.location.host);
  websocket.onopen = function (evt) { onOpen(evt) };
  websocket.onclose = function (evt) { onClose(evt) };
  websocket.onmessage = function (evt) { onMessage(evt) };
  websocket.onerror = function (evt) { onError(evt) };

連線建立後就可以對服務進行請求,由於websocket預設傳送的Text內容,為了能夠方便呼叫需要制定一些資料格式規劃,在這裡我們首選也是Json.

    function WebSocketSearch() {
        var searchInfo = {
            url: '/listorders', params: { employeeid: $('#lstEmployees').val(), customerid: $('#lstCustomers').val() }
        };
        websocket.send(JSON.stringify(searchInfo));
    }
    function onMessage(evt) {
        var msg = JSON.parse(evt.data);
        var message;
        bindOrders(msg.Data);
    }

請求的資料內容主要包括urlparams,url是描述具體請求的Http地址;params則是描述對應引數名的引數。通過和ajax的查詢程式碼來對比,兩者沒有多大的區別,前者是基於url請求而後者則通過描述一個json來處理。

API呼叫方式檢視

FastHttpApi內部整合了一個API查詢面頁,通過這個頁面可以查詢當前服務下所有可訪問的介面,並描述介面在ajax和websocket下的訪問呼叫方式和相關資料格式。訪問路徑/_info/api.html

總結

如果你想開發一個介面服務相同時支援ajax和websocket訪問的話,那FastHttpApi會是不錯的選擇,因為它能提供方便,高效和安全的應用服務介面編寫基礎服務功能。 本文例子的專案程式碼:/samples/HttpApiServer.HttpAndWebsocketApi

相關文章