目录
在next项目当中,可以在客户端组件当中使用centrifuge,进行websocket请求。
一、创建nextjs项目
使用create-next-app来启动一个新的Next.js应用,它会自动为你设置好一切
运行命令:
npx create-next-app@latest
二、安装centrifuge
pnpm add centrifuge
三、创建一个组件HomeCounter.tsx
1、封装请求websocket接口函数
const statistics = 'statistics';
// 请求websocket锁所使用的URL和token
const handleGetWebsocket = async () => {
try {
const res = await fetch(
'http://192.168.1.192:7089/api/v1/websocket_token'
);
const data = await res.json();
console.log(
'🚀 ~ file: hello.html:23 ~ handleGetWebsocket ~ data:',
data
);
return data.data;
} catch (error) {}
};
// 请求订阅的token
async function handleSubscriptionToken(path, token) {
try {
// ctx argument has a channel.
const res = await fetch(
`http://192.168.1.192:7089/api/v1/websocket_token/${path}`,
{
method: 'Get',
headers: new Headers({
'Content-Type': 'application/json',
Authorization: token
})
}
);
const data = await res.json();
return data.data.token;
} catch (error) {}
}
以上两个函数都是我的项目当中所使用过的,读者可以根据自己的实际情况进行操作,不必完全照抄。
2、在组件当中使用centrifuge
在组件HomeCounter.tsx,当中使用centrifuge:
'use client';
import { useEffect, useState, useCallback, memo } from 'react';
import { useTranslation } from '@/i18n/client';
import { ILanguages } from '@/i18n/config';
import { useParams } from 'next/navigation';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import Stack from '@mui/material/Stack';
import Paper from '@mui/material/Paper';
import {
handleGetStatistics,
handleGetWebsocket,
handleSubscriptionToken
} from '@/plugins/request/api';
import { statisticsType, statisticsItem } from '@/dataType';
import util from '@/plugins/util';
import { Centrifuge } from 'centrifuge';
const HomeCounter = () => {
const params = useParams();
const { t } = useTranslation(params?.lng as ILanguages);
const [statistics, setStatistics] = useState<statisticsType | null>();
const [socket, setSocket] = useState<any>(null);
const handletStatistics = useCallback(async () => {
// 这是接口请求函数,在调用websocket之前可以先用接口获取数据,获取的数据与websocket相同,不是必须得
const data = await handleGetStatistics();
// 获取websocket 所必须得URL和token
const webScoket = await handleGetWebsocket();
setStatistics(data);
const centrifuge = new Centrifuge(webScoket!.url, {
token: webScoket!.token
});
setSocket(centrifuge);
// centrifuge正在连接
centrifuge.on('connecting', function (ctx) {
console.log('🚀 ~ file: HomeCounter.tsx:52 ~ ctx:', ctx);
// do whatever you need in case of connecting to a server
});
// centrifuge已经连接
centrifuge.on('connected', function (ctx) {
console.log('🚀 ~ file: HomeCounter.tsx:45 ~ ctx:', ctx);
// now client connected to Centrifugo and authenticated.
});
// centrifuge连接断开
centrifuge.on('disconnected', function (ctx) {
console.log('🚀 ~ file: HomeCounter.tsx:47 ~ centrifuge.on ~ ctx:', ctx);
// do whatever you need in case of disconnect from server
});
// centrifuge连接失败
centrifuge.on('error', function (ctx) {
console.log(ctx);
});
// 请求订阅token的参数
const subParams = {
channel: 'statistics',
token: webScoket!.token
};
// 请求订阅token接口调用,可以根据实际情况来
const subData = await handleSubscriptionToken(subParams);
// 在订阅token失效后,重新点阅函数
async function handleGetSubscriptionToken() {
const params = {
channel: 'statistics',
token: webScoket!.token
};
const data = await handleSubscriptionToken(params);
return data!.token;
}
// 通道订阅,其中statistics是通道名称
const sub = centrifuge.newSubscription('statistics', {
token: subData?.token,
getToken: handleGetSubscriptionToken
});
// 订阅成功后返回数据接收
sub.on('publication', function (ctx) {
console.log(ctx.data);
setStatistics(ctx.data);
});
//调用订阅
sub.subscribe();
// 连接websocket
centrifuge.connect();
}, []);
useEffect(() => {
// websocket请求
handletStatistics();
}, [handletStatistics]);
// 断开websocket连接
useEffect(() => {
return () => {
if (socket) {
socket.disconnect();
}
};
}, [socket]);
return (
<Grid container spacing={5}>
{statistics
? (Object.keys(labelLang) as any).map((item: statisticsItem) => {
return (
<Grid item xs={3} key={item}>
{statisticsItem}
</Grid>
);
})
: ''}
</Grid>
);
};
export default memo(HomeCounter);
以上就是在nextjs框架当中使用centrifuge最新版本的实例,具体参见centrifuge github