使用socket.io搭建一个实时聊天机器人

Posted 小小白学计算机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用socket.io搭建一个实时聊天机器人相关的知识,希望对你有一定的参考价值。

一、安装socket.io

npm i socket.io --save

二、使用

第一种:服务端使用原生node

// 创建http服务器
const http = require('http')
var fs = require('fs')
const app = http.createServer()

app.on('request', (req, res) => {
    fs.readFile(__dirname + '/index.html', function (err, data) {
        if (err) {
            res.writeHead(500)
            return res.end('Error loding!')
        }

        res.writeHead(200)
        res.end(data)
    })
})

app.listen(3000, () => {
    console.log('服务器启动成功,正在监听3000端口...')
})
const io = require('socket.io')(app,  { cors: true }) // cors: true 表示允许跨域
// socket.emit() 表示发送某个事件
// socket.on() 表示监听某个事件
// 监听了用户连接的事件
io.on('connection', socket => {
    console.log('新用户连接了!')
    // socket.emit() 标识给浏览器发送数据
    // 参数1: 事件的名字
    socket.emit('send', { name: 'zep' })
})

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index2</title>
</head>
<body>
    <h2>哈哈哈哈</h2>


    <script src="/socket.io/socket.io.js"></script>
    <script>
        // 连接socket服务
        var socket = io.connect('ws://localhost:3000')
        // 监听send事件,得到服务器返回的数据
        socket.on('send', (data) => {
            console.log(data);
        })
    </script>
</body>
</html>



第二种: 服务端使用express

var app = require('express')()
var server = require('http').Server(app)
var io = require('socket.io')(server, { cors: true })

server.listen(3000, () => {
    console.log('服务器启动成功,正在监听3000端口...')
})

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html')
})

io.on('connection', function (socket) {
    console.log('新用户连接了!')
    socket.emit('send', { name: 'zep' })
    socket.on('other', function (data) {
        console.log(data);
    })
})

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index2</title>
</head>
<body>
    <h2>哈哈哈哈</h2>


    <script src="/socket.io/socket.io.js"></script>
    <script>
        // 连接socket服务
        var socket = io.connect('ws://localhost:3000')
        // 监听send事件,得到服务器返回的数据
        socket.on('send', (data) => {
            console.log(data);
        })
        socket.emit('other', { age: 22 })
    </script>
</body>
</html>


三、案例 : 聊天机器人(结合天行机器人api



1. 使用express搭建后端服务器(结合socket.io)

var app = require('express')()
var server = require('http').Server(app)
var io = require('socket.io')(server, { cors: true })
const axios = require("axios");
server.listen(3000, () => {
    console.log('服务器启动成功,正在监听3000端口...')
})

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html')
})

async function sendToRobot(data) {
    let response = await axios({
        method: "GET",
        url: 'http://api.tianapi.com/txapi/robot/index',
        params: {
            key: '5fb41161af56441feef854fc',
            question: data
        }
    })
    console.log(typeof (response.data))
    console.log(response.data.newslist[0].reply)
    return response.data
}

io.on('connection', function (socket) {
    console.log('新用户连接了!')
    socket.on('send',async function (data) {
        // 给天行聊天机器人接口发送请求
        let response = await axios({
            method: "GET",
            url: 'http://api.tianapi.com/txapi/robot/index',
            params: {
                key: '5fb41161aff1256441d57eef854fc',
                question: data
            }
        })
        const newData = {
            // msg: data.msg + '???',
            msg: response.data.newslist[0].reply,
            timestamp: Date.now()
        }
        socket.emit('msg', newData)
    })
})

2. 在vue前端中使用:

<template>
  <div class="user-chat">
    <!--导航栏-->
    <van-nav-bar
      class="app-nav-bar"
      title="小智同学"
      left-arrow
      @click-left="$router.back()"
    />
    <!--消息列表-->
    <van-cell-group class="message-list" ref="message-list">
<!--      <div v-for="(item, index) in messages" :key="index">-->
        <van-cell class="message-item" center v-for="(item, index) in messages" :key="index">
          <div class="message-item-right" v-if="index % 2 ===0">
            <div class="message-item-text">{{ item.msg }}</div>
            <van-image
              width="40"
              height="40"
              round
              src="https://img01.yzcdn.cn/vant/apple-1.jpg"
            />
          </div>
          <div class="message-item-left" v-else>
            <van-image
              width="40"
              height="40"
              round
              src="https://img01.yzcdn.cn/vant/cat.jpeg"
            />
            <div class="message-item-text">{{ item.msg }}</div>
          </div>
        </van-cell>
<!--      </div>-->
    </van-cell-group>
    <!--发送消息-->
    <van-cell-group class="send-message-wrap">
      <van-field v-model="message"
                 placeholder="请输入消息"
                 :border="false"
      />
      <van-button size="small"
                  type="primary"
                  class="sendBtn"
                  @click="onSend"
      >发送</van-button>
    </van-cell-group>
  </div>
</template>

<script>
import io from 'socket.io-client'
import { setItem, getItem } from '../../utils/storage'

export default {
  name: 'UserChat',
  data () {
    return {
      message: '',
      socket: null, // WebSocket通信对象
      messages: getItem('chat-messages') || [] // 消息列表
    }
  },
  watch: {
    // 监视messages,只要messages的值发生改变就把当前的messages存到本地存储中
    messages () {
      setItem('chat-messages', this.messages)
      // 如果你要在操作数据之后立即操作数据影响的视图DOM,
      // 那么最好放在$nextTick()中
      // 数据改变影响视图更新这件事不是立刻的
      this.$nextTick(() => {
        // 每次有新消息时,让消息列表滚动到最底部
        this.scrollToBottom()
      })
    }
  },
  mounted () {
    this.scrollToBottom()
  },
  created () {
    const socket = io('ws://localhost:3000')
    this.socket = socket
    window.socket = socket
    socket.on('connect', function () {
      console.log('连接建立成功了!')
    })
    // 监听 message 事件,接收服务端消息
    socket.on('msg', (data) => {
      // 把对方发给我的消息放到数组中
      this.messages.push(data)
      console.log(data)
    })
    socket.on('disconnect', function () {
      console.log('断开连接了')
    })
  },
  methods: {
    onSend () {
      // 请求发送消息
      const data = {
        msg: this.message,
        timestamp: Date.now()
      }
      this.socket.emit('send', data)
      // 把用户发出去的消息存储到数组中
      this.messages.push(data)
      // 清空输入框的内容
      this.message = ''
    },
    scrollToBottom () {
      const list = this.$refs['message-list']
      list.scrollTop = list.scrollHeight
    }
  }
}
</script>

<style scoped lang="less">
  .send-message-wrap {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    padding: 0 10px;
  }
  .sendBtn {
    width: 20%;
  }
  .message-list {
    position: fixed;
    left: 0;
    right: 0;
    top: 46px;
    bottom: 44px;
    overflow-y: auto;
  }
  .message-item {
    color: red;
    display: flex;
    align-items: center;
    .message-item-right {
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }
    .message-item-left {
      display: flex;
      align-items: center;
      justify-content: flex-start;
    }
  }
  .message-item-text {
    margin: 0 15px;
  }
</style>

以上是关于使用socket.io搭建一个实时聊天机器人的主要内容,如果未能解决你的问题,请参考以下文章

使用Node.js+Socket.IO搭建WebSocket实时应用

使用Node.js+Socket.IO搭建WebSocket实时应用

使用 node.js、websockets 和 socket.io 创建实时聊天

基于socket.io +koa2 +天行机器人 实现简单人机实时通讯(nginx处理socket.io https代理问题)

使用Node.js+Socket.IO搭建WebSocket实时应用转载

基于 NodeJs 打造 Web 在线聊天室