يسمح socket.handshake.query
حاليًا بتعيين البيانات على connect
، لكن لا يمكن تحديثها بالمرجع قبل إطلاق reconnect
. يتسبب هذا في مشكلة عند السماح باتصال مأخذ برموز التحديث.
//client
io.connect("wss://socket.server.com", {
query : {
token:"something dynamic"
}
});
إذا تم إعادة تشغيل الخادم وعملاء reconnect
، فقد يكون الرمز المميز قديمًا عند إعادة تفويض المقبس.
//server
io.use(function(socket, next) {
var query = socket.handshake.query;
if(isValidToken(query.token)){
next();//will never fire if the token has been updated
}
});
السماح للاستعلام أن يكون function
:
io.connect("wss://socket.server.com", {
query : function(){
return {
token:"something dynamic"
}
}
});
في مُنشئ المقبس الحالي:
if (opts && opts.query) {
this.query = opts.query;
}
يمكن تغييره إلى هذا:
if(opts && opts.query) {
this.query = typeof opts.query == 'function' && opts.query.call(this) || opts.query;
}
+1
إصلاح الخطأ رقم 1086 يجب أن يحل مشكلتك أيضًا. كان تغيير خيارات الاستعلام بعد الاتصال الناجح يعمل مع إصدار أقدم من socket.io-client ، ولكن مع الإصدار الحالي يتم فقد المرجع إلى كائن الاستعلام :(
reeltimedoktor حاليا يجب أن تكون قادرا على تحديث query
الكائن على reconnect_attempt
الحدث:
socket.on('reconnect_attempt', function () {
socket.io.opts.query = { token: /* ... */ };
});
يبدو أن حل darrachequesne لا يعمل بالنسبة لي :(
أنا أستخدم socket.io-client
version 2.3.0
على العميل ، مع خادم عقدة بإصدار socket.io
2.3.0
.
بالنسبة للعميل الذي أفعله:
socket.on('reconnect_attempt', async () => {
const newToken = await getNewToken();
socket.io.opts.query = {
token: latestToken,
};
});
وبعد ذلك يقوم الخادم بمصادقة الرمز المميز باستخدام برنامج وسيط تم تمريره إلى io.use()
(والذي يجب تشغيله بعد ذلك عند توصيل المقبس أو إعادة الاتصال ، afaik؟).
في الوقت الحالي ، تفشل مصادقة الخادم في إعادة الاتصال ، قائلة إن الرمز المميز قد انتهى - يبدو أن الرمز المميز الجديد لم يتم تعيينه بشكل صحيح إلى socket.io.opts.query.token
- أي أفكار لماذا؟
شكرا :)
تحديث: يبدو أن هناك مجموعة من الأماكن المختلفة في كائن المقبس حيث يتم تخزين رمز المصادقة ، على سبيل المثال socket.io.engine.query.token
، socket.io.engine.transport.query.token
. لا يتم ملؤها تلقائيًا عند تعيين socket.io.opts.query.token
. ومع ذلك ، فإن تغيير هذه لا يزال لا يؤثر على ما "تراه" الخوادم - فهي لا تزال ترى الرمز القديم فقط.
يبدو أيضًا أنه تم تضمين الرمز المميز كمعامل URL في بعض حقول عنوان url في كائن المقبس. ربما هذه تحتاج إلى التحديث أيضا؟
بعد التحقيق أبعد من ذلك، يبدو أن وضع مميز على socket.io.opts.query.token
غير كافية لتغيير رمز لإعادة المصادقة على اعادة ربط - يبدو شيء آخر أن المشكلة لبلدي التطبيق، وربما أن تفعل شيئا مع firebase المصادقة جيل رمزي. لذلك بالنسبة لأي شخص آخر يصادف هذا ، darrachequesne يعمل!
حسنًا ، أعتقد أنني قمت بإصلاحه - تحتاج إلى التأكد من حصولك على الرمز المميز الجديد بشكل متزامن في رد الاتصال "recnect_attempt" ، أي لا تفعل هذا:
socket.on('reconnect_attempt', async () => {
const newToken = await getNewToken(); // won't work
socket.io.opts.query = {
token: latestToken,
};
});
يبدو أنه تم إجراء المصادقة من جانب الخادم قبل تعيين الرمز المميز الجديد. إذا حصلت على الرمز المميز بشكل متزامن (عن طريق الحصول عليه في وقت سابق وتخزينه ، ثم استعادته فقط في رد اتصال المستمع) ، يحصل الخادم على رمز المصادقة الجديد في الوقت المناسب لإعادة مصادقة الاتصال.
مع "socket.io-client": "3.0.4"
يظهر لي خطأ TS2341: Property 'opts' is private and only accessible within class 'Manager'.
. أنا أستخدم "typescript": "4.1.3"
حسنًا ، أعتقد أنني قمت بإصلاحه - تحتاج إلى التأكد من حصولك على الرمز المميز الجديد _synchronually_ في رد الاتصال "recnect_attempt" ، أي لا تفعل هذا:
socket.on('reconnect_attempt', async () => { const newToken = await getNewToken(); // won't work socket.io.opts.query = { token: latestToken, }; });
يبدو أنه تم إجراء المصادقة من جانب الخادم قبل تعيين الرمز المميز الجديد. إذا حصلت على الرمز المميز بشكل متزامن (عن طريق الحصول عليه في وقت سابق وتخزينه ، ثم استعادته فقط في رد اتصال المستمع) ، يحصل الخادم على رمز المصادقة الجديد في الوقت المناسب لإعادة مصادقة الاتصال.
لدينا مشكلة مماثلة. لكن الحل الحالي هو الحصول على disconnect
من جانب الخادم عندما تفشل المصادقة. عند تلقي حدث disconnect
على العميل ، نقوم بإعادة بناء الاستعلام / الرأس باستخدام استدعاء الوعد غير المتزامن. بحلول الوقت الذي يصل فيه إلى الحدث reconnecting
، يكون لديه بالفعل القيمة الجديدة في الاستعلام / العنوان.
لقراء المستقبل:
سلوك الخيار query
في Socket.IO v2 غريب بعض الشيء ، حيث يتم استخدامه في كليهما:
لذلك لست متأكدًا من كيفية إصلاحه بطريقة متوافقة مع الإصدارات السابقة ...
يرجى ملاحظة أن هذا تم إصلاحه في Socket.IO v3 ، حيث يمكنك الآن استخدام الخيار auth
:
// plain object
const socket = io({
auth: {
token: "abc"
}
});
// or with a function
const socket = io({
auth: (cb) => {
cb({
token: "abc"
});
}
});
يجب أن تعمل مع وظيفة async
أيضًا:
const socket = io({
auth: async (cb) => {
cb({
token: "abc"
});
}
});
أنظر أيضا:
التعليق الأكثر فائدة
reeltimedoktor حاليا يجب أن تكون قادرا على تحديث
query
الكائن علىreconnect_attempt
الحدث: