使用PubNub Message Actions API时遭遇500内部服务器错误求助
PubNub addMessageAction 调用返回500内部服务器错误排查与解决
问题背景
开发聊天功能时,使用PubNub的Message Actions API为已发布消息添加isRead动作,调用pubnub.addMessageAction时持续返回500内部服务器错误。
错误响应详情
{ "error": true, "operation": "PNAddActionOperation", "statusCode": 500, "errorData": { "original": null, "response": { "req": { "method": "POST", "url": "https://ps18.pndsn.com/v1/message-actions/my_sub_key/channel/my_channel_name/message/17053072012353411?uuid=my_user_uuid&pnsdk=PubNub-JS-Web%2F7.4.5&l_hist=791&l_pres=1733", "data": { "type": "isRead", "value": true }, "headers": { "content-type": "application/json" } }, "xhr": {}, "text": "<html>\r\n<head><title>500 Internal Server Error</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>500 Internal Server Error</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n", "statusText": "Internal Server Error", "statusCode": 500, "status": 500, "statusType": 5, "info": false, "ok": false, "redirect": false, "clientError": false, "serverError": true, "error": { "status": 500, "method": "POST", "url": "https://ps18.pndsn.com/v1/message-actions/my_sub_key/channel/my_channel_name/message/17053072012353411?uuid=my_user_uuid&pnsdk=PubNub-JS-Web%2F7.4.5&l_hist=791&l_pres=1733" }, "created": false, "accepted": false, "noContent": false, "badRequest": false, "unauthorized": false, "notAcceptable": false, "forbidden": false, "notFound": false, "unprocessableEntity": false, "headers": { "content-length": "588", "content-type": "text/html" }, "header": { "content-length": "588", "content-type": "text/html" }, "type": "text/html", "links": {}, "body": null }, "status": 500 }, "category": "PNUnknownCategory" }
关联代码
let pubnub; const pubnub_publish_key = 'demo' const pubnub_subscribe_key = 'demo' const user_id = 'test_user_id' const my_channel_name = 'test_channel' const setupPubNub = () => { // Initialize PubNub with the publish and subscribe keys and the current user's ID pubnub = new PubNub({ publishKey: pubnub_publish_key, subscribeKey: pubnub_subscribe_key, userId: user_id, reconnectPolicy: 'linear' }); await pubnub.subscribe({ channels: [my_channel_name], presence: true, }); fetchMessages(my_channel_name) const listener = { status: (statusEvent) => { if (statusEvent.category === "PNConnectedCategory") { console.log("Connected") } }, message: (messageEvent) => { console.log(messageEvent) }, presence: function(presenceEvent) { console.log(presenceEvent) } }; pubnub.addListener(listener); }; window.onload = setupPubNub; window.onbeforeunload = (event) => { pubnub.unsubscribeAll(); } // Asynchronous function to fetch messages from a channel const fetchMessages = async(channelName) => { try { // Fetch messages from the channel await pubnub.fetchMessages({ channels: [channelName], count: 100, stringifiedTimeToken: true, }, (status, response) => { if (status.error) { throw new Error(JSON.stringify(status)); } else { // Encode the channel name (becaues it contains a colon) const encodedChannelName = encodeURIComponent(channelName) if (response) { // Get the messages from the response const messages = response.channels[encodedChannelName] // If there are messages if (messages) { // Wrap the loop in an async function (async() => { // For each message for (let i = 0; i < messages.length; i++) { let { uuid, timetoken, message: { text: messageText } } = messages[i]; //other code goes here to insert the message text and time to ket to the ui. Removed it becasue it doesn't matter for the error i am getting // If this is the last message if (i == messages.length - 1) { let lastMessageTimetoken = messages[i]?.timetoken //logs the last message data properly console.log(channelName, lastMessageTimetoken) const isRead = messages[i].message?.isRead ? true : await updateIsRead(channelName, lastMessageTimetoken); console.log(isRead) } } })(); } } } }); } catch (error) { // Log any errors that occurred console.error(`Error in fetchMessages: ${error.message}`); } } //this is where i get the error const updateIsRead = async(channelName, timetoken) => { if (typeof channelName !== 'string' || typeof timetoken !== 'string') { console.error('Invalid parameters'); return; } await pubnub.addMessageAction({ channel: channelName, messageTimetoken: timetoken, action: { type: 'isRead', value: true, }, }, function(status, response) { if (status.error) { return status } else { return response } } ); }
排查与解决建议
修正异步代码混用问题:
setupPubNub未标记为async却使用await,会直接导致初始化失败,需改为async setupPubNub。fetchMessages和updateIsRead同时混用await与回调函数,会导致异步流程混乱,建议统一使用Promise风格(去掉回调,直接用await接收返回值)。
检查timetoken有效性:
确认从fetchMessages返回的timetoken是完整的有效字符串(PubNub timetoken通常为17位及以上),无效的timetoken会导致服务器解析失败触发500错误。替换Demo密钥:
公共demo密钥存在功能限制,大概率不支持Message Actions,需替换为自己的PubNub套餐密钥,并确保Message Actions权限已开启。通道名称处理:
addMessageAction的channel参数需传入原始未编码的通道名,SDK会自动处理特殊字符编码,传入已编码名称会导致服务器无法识别通道。升级SDK版本:
当前使用的7.4.5版本可能存在已知bug,建议升级到最新稳定版后重试。
内容的提问来源于stack exchange,提问作者seriously
相关产品推荐
相关产品推荐

