socket.io 自动和手动连接服务
手动管理连接
客户端初始化
// src/utils/socket.ts
import { io } from 'socket.io-client';
export const socket = io('ws://localhost:3001', {
autoConnect: false,
// transports: ['websocket'],
auth: (cb: (token: object) => void) => {
cb({ token: localStorage.getItem('token') });
},
});
参数介绍
autoConnect默认为true。客户端立即打开与服务器的连接。设置false后,需要手动维护ws连接。auth携带鉴权信息。服务端获取方式:client.handshake?.auth?.token
管理连接伪代码
useEffect(() => {
const onConnect = () => {
console.log('connected');
socket.volatile.emit('joinRoom', {
chatroomId: chatroomId,
});
};
const onConnectError = (err: any) => {
console.log('error', err);
};
const onDisconnect = (reason: Socket.DisconnectReason) => {
console.log('disconnect', reason);
};
socket.on('connect', onConnect);
socket.on('connect_error', onConnectError);
socket.on('disconnect', onDisconnect);
socket.connect();
return () => {
socket.off('connect', onConnect);
socket.off('connect_error', onConnectError);
socket.off('disconnect', onDisconnect);
socket.disconnect();
};
}, [chatroomId]);
ws自动连接
记录伪代码
注意事件要及时解绑
const socketRef = useRef<Socket>(null);
useEffect(() => {
const socket = io('ws://localhost:3001', {
auth(cb) {
cb({
token: localStorage.getItem('token'),
});
},
});
socketRef.current = socket;
const onConnect = () => {
console.log('connected');
socket.volatile.emit('join_room', {
chatroomId: chatroomId,
});
};
const onConnectError = (err: any) => {
console.log('error', err);
};
const onDisconnect = (reason: Socket.DisconnectReason) => {
console.log('disconnect', reason);
};
const onMessage = (data: any) => {
console.log(socket.id, 'socketId');
console.log('message', data);
};
socket.on('connect', onConnect);
socket.on('connect_error', onConnectError);
socket.on('disconnect', onDisconnect);
socket.on('message', onMessage);
return () => {
socket.off('connect', onConnect);
socket.off('connect_error', onConnectError);
socket.off('disconnect', onDisconnect);
socket.off('message', onMessage);
socket.disconnect();
};
}, [chatroomId]);
简易聊天室,前端代码
- 初始化socket
import { io } from 'socket.io-client';
export const socket = io('ws://localhost:3001', {
autoConnect: false,
// transports: ['websocket'],
auth: (cb: (token: object) => void) => {
cb({ token: localStorage.getItem('token') });
},
});
- 切换room时,实现房间的进出。不完整代码如下
function ChatRoom({ chatroomId }: { chatroomId: number }) {
const [chatList, setChatList] = useState<Message[]>([]);
useEffect(() => {
if (!chatroomId) return;
socket.emit('join_room', { chatroomId }, ([res, error]: any) => {
if (error) {
console.log('join room error', error);
return;
}
console.log('join room', res);
});
return () => {
socket.emit('leave_room', { chatroomId });
};
}, [chatroomId]);
useEffect(() => {
const onMessage = (data: any) => {
console.log('message', data);
setChatList((prev) => {
return [...prev, data];
});
};
socket.on('message', onMessage);
return () => {
socket.off('message', onMessage);
};
}, []);
return (
<div className="pl-5 pt-10">
some things
</div>
);
}