需要前后端实现连接方可通信
前端部分react- demo
安装依赖
yarn add socket.io-client
src\app.ts
const { io } = require("socket.io-client");
const socket = io('http://localhost:3000',{
withCredentials: true,
});
console.log('vv',socket);
// client-side
socket.on("connect", () => {
console.log('con',socket.id);
});
socket.on("disconnect", () => {
console.log('fail',socket.id);
});
后端部分node- demo
安装依赖
npm install socket.io
server\index.js
const http = require('http')
const server = http.createServer(function (req, res) {})
module.exports = {
server
}
db\index.js
const mongodb = require('mongoose')
const connectDB = async () => {
return await mongodb.connect("mongodb://127.0.0.1:27017/note")
}
module.exports = {
connectDB
}
index.js
const {
server
} = require('./server/index')
const {
Server
} = require('socket.io');
const {
connectDB
} = require("./db/index.js")
const User = require("./controller/user")
const Url = require('node:url');
const fs = require('node:fs');
const io = new Server(server, {
cors: {
origin: "http://localhost:8000",
credentials: true
}
})
// 连接mongodb数据库
connectDB().then(res => {})
// 监听请求
server.on('request', async function (req, res) {
const {
method,
url,
} = req
const {
pathname,
} = Url.parse(url)
if (method === 'GET') {
if (pathname === '/user') {
User.get(req, res)
}
if (pathname === '/home') {
res.writeHead(200, {
'Content-type': 'text/html'
})
res.end(fs.readFileSync("./view/home.html"))
}
} else if (method === 'POST') {
if (pathname === '/user') {
User.bitchAdd(req, res)
}
// if (pathname === '/file') {
// console.log('v', req)
// res.end(JSON.stringify({
// code: -1,
// data: null,
// msg: 'fail'
// }))
// }
} else if (method === 'DELETE') {
if (pathname === '/user') {
User.del(req, res)
}
} else if (method === 'PUT') {
}
})
io.on("connection", (socket) => {
console.log('socket-connection');
});
server.listen(3000, "localhost", () => {
// console.log('listen');
})
需要前后端共同启动项目开启才可连接成功。
出现跨域问题解决
服务端
const io = new Server(server, {
cors: {
origin: "http://localhost:8000",
credentials: true
}
})
客户端
const socket = io('http://localhost:3000',{
withCredentials: true,
});
demo练习
src\utils\common.ts
const { io } = require("socket.io-client");
const list = localStorage.getItem('chatList')
const keyList = localStorage.getItem('uniqueKeyArr');
let chatList: any[] = []
let uniqueKeyArr: any[] = []
if (list) {
chatList = JSON.parse(list)
}
if (keyList) {
uniqueKeyArr = JSON.parse(keyList)
}
export const socket = io('http://localhost:3000', {
withCredentials: true,
});
// client-side
socket.on("connect", () => {
console.log('con', socket);
});
export const sendMessage = (sender: string, receiver: string, message: any, uniqueKey: string) => {
socket.emit("communicate", uniqueKey, JSON.stringify({
sender,
receiver,
message,
date: new Date()
}));
}
socket.on("communicate", (...args: any[]) => {
console.log('args', args);
debugger
const [key, Obj] = args
if (uniqueKeyArr.includes(key)) {
return;
}
console.log('cache.chatList', chatList);
if (chatList?.length) {
chatList = [...chatList, Obj]
} else {
chatList.push(Obj)
}
localStorage.setItem('chatList', JSON.stringify(chatList))
localStorage.setItem('uniqueKeyArr', JSON.stringify([uniqueKeyArr, key]))
})
src\pages\WeChat\index.tsx
import { sendMessage } from '@/utils/common';
import { connect } from "umi";
import './index.less';
const WeChat = (props: any) => {
const { global } = props
const source = localStorage?.getItem('chatList')
const list = source ? JSON.parse(source) : []
console.log('list', list);
return (
<div className="chat">
<div className="chat-header">Header</div>
<div className="chat-name">{global.userB}</div>
<div className="chat-body">
{
list.map((v: any, i: number) => {
console.log(v),
console.log();
const isMain = global.userB === v.receiver ? 'other-user' : 'main-user'
return (
<div key={i} className={`${isMain}`}>
{ (global.userA === v.sender) ? <></> : <div> {v.receiver}</div>}
<div>
{v.message}
</div>
</div>
)
})
}
</div>
<div className="chat-foot">
<input type="text" />
<button onClick={() => {
console.log('send');
sendMessage( global.userA,global.userB, "HELLO", `${new Date().valueOf()}-${Math.random() * 100}`)
}}>send</button>
</div>
</div>
)
}
export default connect(((state) => {
return { global: state.CHAT }
}))(WeChat)
.chat {
.chat-header {
background-color: palevioletred;
height: 30px;
}
.chat-name {
background-color: aquamarine;
text-align: center;
height: 40px;
align-items: center;
justify-content: center;
display: flex;
}
.other-user {
text-align: left;
}
.main-user {
text-align: right;
}
.chat-foot {
position: fixed;
bottom: 0;
height: 40px;
width: 100%;
}
}
src\pages\WeChatB\index.tsx
import { sendMessage } from '@/utils/common';
import { connect } from "umi";
import './index.less';
const WeChar = (props: any) => {
const { global } = props
const source = localStorage?.getItem('chatList')
const list = source ? JSON.parse(source) : []
console.log('list', list);
return (
<div className="chat">
<div className="chat-header">Header</div>
<div className="chat-name">{global.userA}</div>
<div className="chat-body">
{
list.map((v: any, i: number) => {
console.log(v),
console.log();
const isMain = global.userA === v.receiver ? 'other-user' : 'main-user'
return (
<div key={i} className={`${isMain} item-list`}>
<div className='logo'>
{(global.userB === v.sender) ? <></> : <div> {v.receiver}</div>}
<div className='header-logo'></div>
</div>
<div className='msg'>
{v.message}
</div>
</div>
)
})
}
</div>
<div className="chat-foot">
<input type="text" />
<button onClick={() => {
console.log('send');
sendMessage(global.userB, global.userA, "HELLO", `${new Date().valueOf()}-${Math.random() * 100}`)
}}>send</button>
</div>
</div>
)
}
export default connect(((state) => {
return { global: state.CHAT }
}))(WeChar)
.chat {
.chat-header {
background-color: palevioletred;
height: 30px;
}
.chat-name {
background-color: aquamarine;
text-align: center;
height: 40px;
align-items: center;
justify-content: center;
display: flex;
}
.item-list {
display: flex;
.logo {
margin-left: 10px;
margin-right: 10px;
}
.header-logo {
display: inline-block;
background-color: aquamarine;
height: 30px;
width: 30px;
border-radius: 2px;
}
}
.other-user {
flex-direction: row;
}
.main-user {
flex-direction: row-reverse;
}
.chat-foot {
position: fixed;
bottom: 0;
height: 40px;
width: 100%;
}
}
node项
const {
server
} = require('./server/index')
const {
Server
} = require('socket.io');
const {
connectDB
} = require("./db/index.js")
const User = require("./controller/user")
const Url = require('node:url');
const fs = require('node:fs');
const io = new Server(server, {
cors: {
origin: "http://localhost:8000",
credentials: true
}
})
// 连接mongodb数据库
connectDB().then(res => {})
// 监听请求
server.on('request', async function (req, res) {
const {
method,
url,
} = req
const {
pathname,
} = Url.parse(url)
if (method === 'GET') {
if (pathname === '/user') {
User.get(req, res)
}
if (pathname === '/home') {
res.writeHead(200, {
'Content-type': 'text/html'
})
res.end(fs.readFileSync("./view/home.html"))
}
} else if (method === 'POST') {
if (pathname === '/user') {
User.bitchAdd(req, res)
}
// if (pathname === '/file') {
// console.log('v', req)
// res.end(JSON.stringify({
// code: -1,
// data: null,
// msg: 'fail'
// }))
// }
} else if (method === 'DELETE') {
if (pathname === '/user') {
User.del(req, res)
}
} else if (method === 'PUT') {
}
})
io.on("connection", (socket) => {
// console.log('socket',socket.rooms);
socket.on("communicate", (...args) => {
console.log('node', args);
socket.emit("communicate",args[0], JSON.parse(args[1]) );
});
// console.log('socket-connection');
socket.on("disconnect", (reason) => {
console.log(reason,'reason');
});
});
server.listen(3000, "localhost", () => {
// console.log('listen');
})