Socket.io广播代码报错修复请求:TypeError与SyntaxError问题
问题修复请求:Socket.io广播事件报错处理
报错场景1
执行客户端代码:
socket.emit("broadcasting", { cmd: "new" });
报错信息:
0|server | TypeError: Cannot set property 'id' of undefined
报错场景2
执行客户端代码:
socket.emit("broadcasting", { cmd: "send" });
报错信息:
0|server | SyntaxError: Unexpected token u in JSON at position 0
对应服务端处理代码
socket.on("broadcasting", (data) => { if (typeof data != "object") { return; } if(UserInfo[socket.id]){ if (data.cmd == "new") { if (UserInfo[socket.id].rep >= SiteSetting["miclikes"]) { io.to(UserInfo[socket.id].idroom).emit("broadcasting", { cmd: "new", it: data.it, user:socket.id }); socket.emit("broadcasting", { cmd: "new", it: data.it }); PeerRoom[UserInfo[socket.id].idroom][data.it].id = socket.id; PeerRoom[UserInfo[socket.id].idroom][data.it].ev = true; } else { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: SiteSetting["miclikes"] + " " + "عدد الايكات المطلوبة للمايك", user: "", }, }); } } else if (data.cmd == "send") { const myfr = JSON.parse(data.mj); if (myfr.type == "new-ice-candidate") { socket.to(myfr["target"]).emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr["type"], it: myfr["it"], target: myfr["target"], user: socket.id, candidate: myfr["candidate"], }), }); } else if (myfr.type == "video-offer") { socket.to(myfr["target"]).broadcast.emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr["type"], it: myfr["it"], target: myfr["target"], sdp: myfr["sdp"], user: socket.id, }), }); } else if (myfr["type"] == "hang-up") { // if(myfr["target"] == socket.id || VerRoomsOwner(UserInfo[socket.id].power)){ if( PeerRoom[UserInfo[socket.id].idroom][myfr["it"]]){ PeerRoom[UserInfo[socket.id].idroom][myfr["it"]].id = ""; PeerRoom[UserInfo[socket.id].idroom][myfr["it"]].ev = false; io.to(UserInfo[socket.id].idroom).emit("broadcasting", { cmd: "send", msgString: data.mj }); }; } else if (myfr["type"] == "video-answer") { socket.to(myfr["target"]).emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr["type"], it: myfr["it"], target: myfr["target"], sdp: myfr["sdp"], user: socket.id, }), }); } else { io.to(UserInfo[socket.id].idroom).emit("broadcasting", { cmd: "send", msgString: data.mj }); } } } });
错误原因及修复方案
报错1原因与修复
- 原因:客户端发送
new命令时未携带it字段,导致data.it为undefined,进而PeerRoom[UserInfo[socket.id].idroom][data.it]指向undefined,无法设置id属性;同时未校验PeerRoom中房间和对应it项是否存在。 - 修复:增加
data.it参数校验,同时初始化PeerRoom中缺失的结构。
报错2原因与修复
- 原因:客户端发送
send命令时未携带mj字段,data.mj为undefined,执行JSON.parse(undefined)触发语法错误;未处理JSON解析失败的情况。 - 修复:校验
data.mj是否存在且为合法字符串,对JSON解析增加异常捕获。
修复后的完整服务端代码
socket.on("broadcasting", (data) => { if (typeof data !== "object" || data === null) { return; } if (!UserInfo[socket.id]) { return; } const userRoom = UserInfo[socket.id].idroom; if (!userRoom || !PeerRoom[userRoom]) { return; } if (data.cmd === "new") { if (!data.it) { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: "缺少必要参数:it", user: "", }, }); return; } if (UserInfo[socket.id].rep >= SiteSetting["miclikes"]) { if (!PeerRoom[userRoom][data.it]) { PeerRoom[userRoom][data.it] = { id: "", ev: false }; } io.to(userRoom).emit("broadcasting", { cmd: "new", it: data.it, user: socket.id }); socket.emit("broadcasting", { cmd: "new", it: data.it }); PeerRoom[userRoom][data.it].id = socket.id; PeerRoom[userRoom][data.it].ev = true; } else { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: `${SiteSetting["miclikes"]} عدد الايكات المطلوبة للمايك`, user: "", }, }); } } else if (data.cmd === "send") { if (!data.mj || typeof data.mj !== "string") { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: "缺少有效参数:mj", user: "", }, }); return; } let myfr; try { myfr = JSON.parse(data.mj); } catch (err) { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: "mj参数不是合法的JSON格式", user: "", }, }); return; } if (!myfr.type) { socket.emit("msg", { cmd: "not", data: { topic: "", force: 1, msg: "缺少必要字段:type", user: "", }, }); return; } if (myfr.type === "new-ice-candidate") { if (!myfr.target || !myfr.it || !myfr.candidate) { socket.emit("msg", { cmd: "not", data: { topic: "", force:1, msg: "new-ice-candidate缺少必要参数", user:"" } }); return; } socket.to(myfr.target).emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr.type, it: myfr.it, target: myfr.target, user: socket.id, candidate: myfr.candidate, }), }); } else if (myfr.type === "video-offer") { if (!myfr.target || !myfr.it || !myfr.sdp) { socket.emit("msg", { cmd: "not", data: { topic: "", force:1, msg: "video-offer缺少必要参数", user:"" } }); return; } socket.to(myfr.target).broadcast.emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr.type, it: myfr.it, target: myfr.target, sdp: myfr.sdp, user: socket.id, }), }); } else if (myfr.type === "hang-up") { if (!myfr.it) { socket.emit("msg", { cmd: "not", data: { topic: "", force:1, msg: "hang-up缺少必要参数:it", user:"" } }); return; } if (PeerRoom[userRoom][myfr.it]) { PeerRoom[userRoom][myfr.it].id = ""; PeerRoom[userRoom][myfr.it].ev = false; io.to(userRoom).emit("broadcasting", { cmd: "send", msgString: data.mj }); } } else if (myfr.type === "video-answer") { if (!myfr.target || !myfr.it || !myfr.sdp) { socket.emit("msg", { cmd: "not", data: { topic: "", force:1, msg: "video-answer缺少必要参数", user:"" } }); return; } socket.to(myfr.target).emit("broadcasting", { cmd: "send", msgString: JSON.stringify({ type: myfr.type, it: myfr.it, target: myfr.target, sdp: myfr.sdp, user: socket.id, }), }); } else { io.to(userRoom).emit("broadcasting", { cmd: "send", msgString: data.mj }); } } });
额外优化说明
- 全流程增加参数校验,避免客户端缺失参数导致服务端崩溃
- 对JSON解析增加try-catch,捕获非法JSON格式异常
- 提取
userRoom变量,减少重复代码调用 - 统一参数缺失时的错误提示逻辑,提升用户反馈清晰度
内容的提问来源于stack exchange,提问作者jack jeson
相关产品推荐
相关产品推荐

