سؤال

لدي تطبيق ربيعي بسيط مزود بوظيفة websocket وكل شيء يعمل حتى الآن.أريد الآن إرسال رسالة من الخادم الخاص بي إلى عميل محدد باستخدام التعليق التوضيحيSendToUser.هذا يعطيني الخطأ "جارٍ تجاهل الرسالة، لا تتوفر معلومات أساسية".أدرك أنه ليس لدي أي تسجيل دخول على الإطلاق على الخادم الخاص بي، لذا فإن كل مستخدم "مجهول" وليس لديه مدير أساسي (لا أستخدم Spring Security في الوقت الحالي).ولكن كل مستخدم لديه معرف الجلسة.أليس من الممكن استخدام معرف الجلسة بطريقة ما للتمييز بين المستخدمين؟كيف يمكنني تحقيق ذلك حتى يحصل المستخدمون على مبدأ أساسي يتوافق مع معرف الجلسة؟

هل كانت مفيدة؟

المحلول

أعتقد أن الحل قد يكون في تجنب الاستخدام @SendToUser واستخدام الخام SimpMessagingTemplate ولإرسال رسائل إلى الوجهة التي تتحكم فيها للجلسات المفتوحة.

على سبيل المثال.بافتراض أن لديك بعض الهوية لجلسة websocket جديدة، يمكنك الاشتراك في قائمة انتظار باستخدام هذا المعرف في اسم قائمة الانتظار:

stomp.subscribe("/queue/chats" + "-" + mycustomidentifier, onmessage);

الآن، على جانب مستمع Spring websocket، يمكنك توجيه استجاباتك باستخدام SimpMessagingTemplate:

@Controller
public class MyController {


    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/chats")
    public void handleChat(@Payload ChatMessage message) {
        this.simpMessagingTemplate.convertAndSend("/queue/chats-" + "mycustomidentifier", "[" + getTimestamp() + "]:" + message.getMessage());
    }
....

نصائح أخرى

يستخدم @SendToUser وأضف "/user/" أمام قائمة الانتظار عند الاشتراك (جانب المشترك فقط).الباقي يعمل السحر :-)

بدلاً من

Java Server: @SendTo("/topic/showResult")

و

JS Client: stompClient.subscribe('/topic/showResult', function(calResult){  ....

يستخدم:

Java Server: @SentToUser("/topic/showResult")

و

JS Client: stompClient.subscribe('/user/topic/showResult', function(calResult){ ....

بناء على إجابة بيجو واستخدام تم إنشاء معرف الجلسة من خلال Stomp (شكرًا، mariusz2108 في إجابته على سؤال مماثل) ، إليك ما نجح بالنسبة لي (استنادًا إلى المثال الكنسي من الربيع)

عميل SpringFramework:

private SimpMessagingTemplate template;

@Autowired
public GreetingController(SimpMessagingTemplate template) {
    this.template = template;
}

@MessageMapping("/hello")
public void greeting(HelloMessage message, @Header("simpSessionId") String sessionId) throws Exception {
    template.convertAndSend("/queue/greeting-"+sessionId, new Greeting("Hello, " + message.getName()));
}

عميل جافا سكريبت:

function connect() {
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        var sessionId = /\/([^\/]+)\/websocket/.exec(socket._transport.url)[1];
        console.log("connected, session id: " + sessionId);
        stompClient.subscribe('/queue/greeting-'+sessionId, function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

بدلاً من معرف جلسة Stomp، يمكنك استخدام معرف الجلسة الخاص بحاوية الويب الخاصة بك (على سبيل المثال:JSESSIONID) ولكن الآن أصبح ملف تعريف الارتباط هذا لا يمكن الوصول إليه بشكل افتراضي من JavaScript (بالنسبة لـ Tomcat) هذا احتمال أكثر صعوبة.

جرب هذا.عملت بالنسبة لي

giveacodicetagpre.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top