一、安装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-barclass="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-imagewidth="40"height="40"roundsrc="https://img01.yzcdn.cn/vant/apple-1.jpg"/></div><div class="message-item-left" v-else><van-imagewidth="40"height="40"roundsrc="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 = socketwindow.socket = socketsocket.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>