满足在后台向用户推送消息或者发送邮件的功能。
消息推送
使用 socket.io 来实现消息推送。
服务端实现
1.使用 express 启动服务
const app = express();
const httpServer = createServer(app);
httpServer.listen(SERVER_PORT);
wsMsg(app, httpServer);
2.连接 socket
import {Server} from 'socket.io';
const wsMsg = (app, httpServer) => {
const io = new Server(httpServer, {
allowRequest: (req, callback) => callback(null, req.headers.origin === undefined),
});
const msgIO = io.of('/ws-message');
wsStore.msgIO = msgIO;
msgIO.on('connection', async socket => {
socket.on('disconnect', () => {
socket.disconnect(true);
});
socket.on('error', (err) => {
console.error('err.message');
});
socket.on('msg:send', (...args) => {
msgIO.emit('msg:send', ...args);
});
});
return msgIO;
};
3.通过接口触发消息推送
const sendMessage = async (req, res) => {
const {type, title, context, receiver} = req.body;
if (type === 'email') {
if (!receiver) {
return res.status(400).send({message: '请选择接收者!'});
}
sendMail(receiver, title, context);
} else {
if (wsStore.msgIO) {
wsStore.msgIO.emit('msg:send', {title, context});
}
}
};
前端实现
1.配置 socket
import {io} from 'socket.io-client';
const wsMsgUrl = `${window.location.origin}/message`;
export const wsMsg = () => io(wsMsgUrl, {
auth: {Authorization: `auth ${storage.get('token')}`},
// autoConnect: false,
});
2.全局监听
const initWS = () => {
const ws = wsMsg();
ws.on('msg:send', ({title, context}) => {
notification.info({
message: `消息推送:${title}`,
description: context,
});
notifyStore.setState(count => count + 1);
});
ws.on('msg:online', ({userid, count}) => {
notification.info({
message: `${userid} 已上线!`,
description: `当前在线用户数: ${count}`,
});
});
ws.on('msg:offline', ({userid, count}) => {
notification.info({
message: `${userid} 已下线!`,
description: `当前在线用户数: ${count}`,
});
});
};
3.页面监听,获取实时数据
const Index = props => {
const [users, setUsers] = useState([]);
useEffect(() => {
const ws = wsMsg();
ws.on('msg:userinfo', users => {
setUsers(formatUser(users));
});
}, []);
const columns = getColumns();
const count = users.length;
const pagination = {
total: count || 1,
current: 1,
pageSize: count || 10,
};
return (
<Row>
<Col>
<Panel>
<h4>当前在线人数:{count}</h4>
<Table
pagination={pagination}
columns={columns}
dataSource={users}
size="small"
/>
</Panel>
</Col>
</Row>
);
};
发送邮件
使用 nodemailer 来发送邮件。
1.nodejs 服务端配置
import nodemailer from 'nodemailer';
const sendMail = (to, title, context) => {
const transporter = nodemailer.createTransport({
host: 'smtp.xx.com',
port: 465,
secure: true,
auth: {
user: 'xxx',
pass: 'xxx',
},
});
const mailOptions = {
from: '"xxx" xxx',
to,
subject: title,
text: context,
html: context,
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return error;
}
return info;
});
};
2.通过接口发送邮件
const sendMessage = async (req, res) => {
const {type, title, context, receiver} = req.body;
if (type === 'email') {
if (!receiver) {
return res.status(400).send({message: '请选择接收者!'});
}
sendMail(receiver, title, context);
} else {
if (wsStore.msgIO) {
wsStore.msgIO.emit('msg:send', {title, context});
}
}
};