使用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

相关文章
相关标签/搜索