使用websocket開發智能聊天機器人

前面咱們學習了異步web框架(sanic)和http異步調用庫httpx,今天咱們學習websocket技術。javascript

websocket簡介

咱們知道HTTP協議是:請求->響應,若是沒有響應就一直等着,直到超時;可是有時候後臺的處理須要很長時間才能給到結果,好比30分鐘,那HTTP的請求不可能等這麼久,因此,能夠經過 Ajax 輪詢來解決。那就是每間隔一段時間就請求一次。php

這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。html

HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。前端

瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。java

好了,WebSocket就是爲了解決這個問題的,感興趣去看其餘資料!python

智能聊天機器人

我一開始只是爲了學習WebSocket找個例子,很多例子使用了聊天功能。我稍加改進就變成了智能聊天功能了。jquery

經過異步sanic異步框架實現Web功能。官方文檔裏面給個WebSocket使用的例子。git

https://sanic.readthedocs.io/en/latest/sanic/websocket.htmlgithub

snaic部分核心代碼以下:web

import sanic
import httpx
from sanic import Sanic
from sanic.response import json
from sanic.websocket import WebSocketProtocol
from sanic.exceptions import NotFound
from sanic.response import html
from jinja2 import Environment, PackageLoader


env = Environment(loader=PackageLoader('app', 'templates'))

app = Sanic(__name__)


@app.route('/')
async def index(request):
    """
    聊天頁面
    """
    template = env.get_template('index.html')
    html_content = template.render(title='聊天機器人')
    return html(html_content)


@app.websocket('/chat')
async def chat(request, ws):
    """
    處理聊天信息,並返回消息
    """
    while True:
        user_msg = await ws.recv()
        print('Received: ' + user_msg)
        intelligence_data = {"key": "free", "appid": 0, "msg": user_msg}
        r = httpx.get("http://api.qingyunke.com/api.php", params=intelligence_data)
        chat_msg = r.json()["content"]
        print('Sending: ' + chat_msg)
        await ws.send(chat_msg)


if __name__ == "__main__":
    app.error_handler.add(
        NotFound,
        lambda r, e: sanic.response.empty(status=404)
    )
    app.run(host="192.168.0.7", port=8000, protocol=WebSocketProtocol, debug=True)
  • index() 函數,返回聊天頁面。這裏用到了jinja2 模板渲染庫。
  • chat() 函數,經過webSocket實現消息的接收、處理和返回。

智能聊天是怎麼作到的,這裏要感謝 青雲客網絡,他們提供了免費的接口。(我當時也只是抱着試試看的態度,沒想到,duang~! )

user_msg = "你好!"
intelligence_data = {"key": "free", "appid": 0, "msg": user_msg}
r = httpx.get("http://api.qingyunke.com/api.php", params=intelligence_data)
chat_msg = r.json()["content"]
print(chat_msg)

是否是超簡單。

再來看前端代碼,主要部分:

<div class="container theme-showcase" role="main" style="margin-top: 80px;">
      <div id="contents" style="height: 600px; background-color:#eee;"></div>
      <div>
          <textarea class="form-control" id="msg"></textarea>
          <button class="btn btn-lg btn-info" onclick="sendMsg()" style="float: right;">發送</button>
      </div>
  </div>

  <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script type="text/javascript">

          var ws = new WebSocket("ws://192.168.0.7:8000/chat");
          ws.onmessage = function(e) {
              $("#contents").append('<div class="alert alert-info" role="alert" style="float: left;">' + "機器人: " + e.data + "</div><br><br><br><br>");
          }
          function sendMsg() {
              var msg = $("#msg").val();
              $("#contents").append('<div class="alert alert-info" role="alert" style="float:right">' + msg + "</div><br><br><br><br>");
              ws.send(msg);
              $("#msg").val("");
          }

  </script>

這裏使用到了 bootstrap 前端框架,主要 調用部分在:

var Socket = new WebSocket(url, [protocol] );
  • Socket.send(msg): 使用鏈接發送數據。
  • Socket.onmessage: 客戶端接收服務端數據時觸發。

我知道,你火燒眉毛想要完整的代碼了:

https://github.com/defnngj/learning-API-test

相關文章
相關標籤/搜索