@alicloud/bailian20230601 包在next.js14的框架中,进行流式数据请求之前获取token的时候会进行报错
buzhou9 opened this issue · 1 comments
buzhou9 commented
这是用于测试的路由文件代码
// 文件路径 app/api/test-stream/route.ts
import aliTokenHandler from "@/utils/aliTokenHandler";
import {NextRequest, NextResponse} from 'next/server';
export const runtime = 'edge';
async function handler(request: NextRequest, res: NextResponse, token: string) {
const responseStream = new TransformStream();
const writer = responseStream.writable.getWriter();
const encoder = new TextEncoder();
try {
const responseChunks = `This is a response from a NextJS server. Thank you for your message! ${token}`.split(' ');
sendStream(writer, encoder, responseChunks);
} catch (err) {
console.log(JSON.stringify(err));
throw err;
}
return new Response(responseStream.readable, {
headers: {
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache, no-transform',
},
});
function sendStream(
writer: WritableStreamDefaultWriter<any>,
encoder: TextEncoder,
responseChunks: string[],
chunkIndex = 0
) {
setTimeout(() => {
const chunk = responseChunks[chunkIndex];
if (chunk) {
// Sends response back to Deep Chat using the Response format:
// https://deepchat.dev/docs/connect/#Response
writer.write(encoder.encode(`data: ${JSON.stringify({text: `${chunk} `})}\n\n`));
sendStream(writer, encoder, responseChunks, chunkIndex + 1);
} else {
writer.close();
}
}, 70);
}
}
const GET = aliTokenHandler(handler)
export {
GET
}
这是aliTokenHandler封装的方法
// 文件路径 /utils/aliTokenHandler
import {NextRequest, NextResponse} from 'next/server';
import Client from '@alicloud/bailian20230601'
import * as memoryCache from 'memory-cache'
type CallbackFunc = (req: NextRequest, res: NextResponse, token: string) => Promise<NextResponse<Response>> | Promise<Response>;
async function getToken() {
const cacheKey = 'bailian_token'
if (memoryCache.get(cacheKey)) {
return memoryCache.get(cacheKey)
}
const accessKeyId = process.env.ALY_ACCESS_KEY_ID || '';
const accessKeySecret = process.env.ALY_ACCESS_KEY_SECRET || '';
const agentKey = process.env.ALY_BAILIAN_AGENT_KEY || '';
const endpoint = 'bailian.cn-beijing.aliyuncs.com'
// @ts-ignore
const c = new Client({
accessKeyId: accessKeyId,
accessKeySecret: accessKeySecret,
endpoint: endpoint
})
async function createToken() {
const response = await c.createToken(
// @ts-ignore
{ agentKey: agentKey }
);
const responseBody = response.body
if (responseBody === null) {
throw new Error('failed to create token')
}
if (responseBody.success !== true) {
let requestId = responseBody.requestId;
if (requestId == null) {
requestId = response.headers["x-acs-request-id"];
}
let error = "failed to create token " + responseBody.message + ", requestId: " + requestId;
throw new Error(error)
}
const tokenData = responseBody.data
if (!tokenData) {
throw new Error("failed to create token");
}
return tokenData
}
try {
const { token = '', expiredTime = 0} = await createToken()
memoryCache.put(cacheKey, token, expiredTime * 1000 - new Date().getTime());
console.log('token: ' + memoryCache.get(cacheKey) + ', expiredTime: ' + expiredTime);
return token
} catch (err) {
console.error('failed to create token, err: ', err);
throw err
}
}
export default function errorHandler(callbackFunc: CallbackFunc) {
return async (req: NextRequest, res: NextResponse) => {
try {
const token = await getToken()
return await callbackFunc(req, res, token);
} catch (error) {
console.error('API Error:', error);
// Sends response back to Deep Chat using the Response format:
// https://deepchat.dev/docs/connect/#Response
return NextResponse.json({error}, {status: 500});
}
};
}
执行步骤
在浏览器访问 http://localhost:3000/api/test-stream
预期结果
流式输出文本并且返回token
实际结果
报错,以下是控制台错误日志
○ Compiling /api/test-stream ...
⨯ ./node_modules/@alicloud/credentials/dist/src/oidc_role_arn_credential.js:9:29
Module not found: Can't resolve 'fs'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./node_modules/@alicloud/credentials/dist/src/client.js
./node_modules/@alicloud/openapi-client/dist/client.js
./node_modules/@alicloud/bailian20230601/dist/client.js
./src/utils/aliTokenHandler.ts
./src/app/api/test-stream/route.ts
./node_modules/next/dist/build/webpack/loaders/next-edge-app-route-loader/index.js?absolutePagePath=%2FUsers%2Fhuangxiaotong%2Fwork%2Fpenglai%2Fsrc%2Fapp%2Fapi%2Ftest-stream%2Froute.ts&page=%2Fapi%2Ftest-stream%2Froute&appDirLoader=bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBpJTJGdGVzdC1zdHJlYW0lMkZyb3V0ZSZwYWdlPSUyRmFwaSUyRnRlc3Qtc3RyZWFtJTJGcm91dGUmYXBwUGF0aHM9JnBhZ2VQYXRoPXByaXZhdGUtbmV4dC1hcHAtZGlyJTJGYXBpJTJGdGVzdC1zdHJlYW0lMkZyb3V0ZS50cyZhcHBEaXI9JTJGVXNlcnMlMkZodWFuZ3hpYW90b25nJTJGd29yayUyRnBlbmdsYWklMkZzcmMlMkZhcHAmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZyb290RGlyPSUyRlVzZXJzJTJGaHVhbmd4aWFvdG9uZyUyRndvcmslMkZwZW5nbGFpJmlzRGV2PXRydWUmdHNjb25maWdQYXRoPXRzY29uZmlnLmpzb24mYmFzZVBhdGg9JmFzc2V0UHJlZml4PSZuZXh0Q29uZmlnT3V0cHV0PSZwcmVmZXJyZWRSZWdpb249Jm1pZGRsZXdhcmVDb25maWc9ZTMwJTNEIQ%3D%3D&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!
⚠ ./node_modules/sax/lib/sax.js
Module not found: Can't resolve 'stream' in '/Users/huangxiaotong/work/penglai/node_modules/sax/lib'
Import trace for requested module:
./node_modules/sax/lib/sax.js
./node_modules/xml2js/lib/parser.js
./node_modules/xml2js/lib/xml2js.js
./node_modules/@alicloud/tea-xml/dist/client.js
./node_modules/@alicloud/openapi-client/dist/client.js
./node_modules/@alicloud/bailian20230601/dist/client.js
./src/utils/aliTokenHandler.ts
./src/app/api/test-stream/route.ts
./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Ftest-stream%2Froute&page=%2Fapi%2Ftest-stream%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Ftest-stream%2Froute.ts&appDir=%2FUsers%2Fhuangxiaotong%2Fwork%2Fpenglai%2Fsrc%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2FUsers%2Fhuangxiaotong%2Fwork%2Fpenglai&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./src/app/api/test-stream/route.ts?__next_edge_ssr_entry__
⚠ Fast Refresh had to perform a full reload due to a runtime error.
当我不使用流式返回的时候这个API工作是正常的
return NextResponse.json({text: `This is a respone from a NextJS edge server. Thankyou for your message! ${token}`});
我现在需要接入通义千问大模型的流式传输的接口,无法以这种形式去创建token
buzhou9 commented
export const runtime = 'edge';
改为
export const config = {
runtime: 'edge',
};
就成功了,不知道为什么