স্প্রিং ওয়েবসাইটকেটে নির্দিষ্ট ব্যবহারকারীর কাছে বার্তা প্রেরণ


87

কেবলমাত্র নির্দিষ্ট ব্যবহারকারীর কাছে সার্ভার থেকে ওয়েবসকেট বার্তা কীভাবে প্রেরণ করবেন?

আমার ওয়েব অ্যাপে বসন্ত সুরক্ষা সেটআপ রয়েছে এবং ওয়েবসকেট ব্যবহার করা হয়েছে। কেবলমাত্র নির্দিষ্ট ব্যবহারকারীর কাছে সার্ভার থেকে বার্তা প্রেরণ করার চেষ্টা করার সময় আমি জটিল সমস্যার মুখোমুখি হয়েছি ।

ম্যানুয়ালটি পড়া থেকে আমার বোঝার বিষয়টি আমরা যে সার্ভারটি করতে পারি তা থেকে

simpMessagingTemplate.convertAndSend("/user/{username}/reply", reply);

এবং ক্লায়েন্ট পক্ষের:

stompClient.subscribe('/user/reply', handler);

তবে আমি কখনই সাবস্ক্রিপশন কলব্যাক আহ্বান করতে পারিনি। আমি অনেক বিভিন্ন পথ চেষ্টা করেছি তবে ভাগ্য নেই।

আমি যদি এটি / টপিক / জবাব প্রেরণ করি তবে এটি কাজ করে তবে অন্যান্য সংযুক্ত ব্যবহারকারীরাও এটি পাবেন।

সমস্যাটি চিত্রিত করতে আমি এই ছোট প্রকল্পটি গিথুবে তৈরি করেছি: https://github.com/gerrytan/wsproblem

ধাপ পুনর্গঠন কর:

1) প্রকল্পটি ক্লোন করুন এবং তৈরি করুন (নিশ্চিত করুন যে আপনি jdk 1.7 এবং maven 3.1 ব্যবহার করছেন)

$ git clone https://github.com/gerrytan/wsproblem.git
$ cd wsproblem
$ mvn jetty:run

২) http://localhost:8080বব / টেস্ট বা জিম / টেস্ট ব্যবহার করে লগইন করুন

3) "অনুরোধের জন্য ব্যবহারকারী নির্দিষ্ট নাম" ক্লিক করুন। প্রত্যাশিত: "হ্যালো {ব্যবহারকারীর নাম}" একটি বার্তা কেবলমাত্র এই ব্যবহারকারীর জন্য "কেবল আমার কাছে প্রাপ্ত বার্তা" এর পরে প্রদর্শিত হবে, প্রকৃত: কিছুই প্রাপ্ত হয়নি


আপনি কি রূপান্তর এন্ডসেন্ডটিওউসার (স্ট্রিং ব্যবহারকারী, স্ট্রিং গন্তব্য, টি বার্তা) এর দিকে তাকিয়ে আছেন? docs.spring.io/spring/docs/4.0.0.M3/javadoc-api/org/…
ভিক্টর কে

হ্যাঁ এটি চেষ্টা
করেও

আমি বেসরকারী প্রকল্পে কাজ করে যাচ্ছি এবং এটিই আমরা ব্যবহার করি এবং এটি আমাদের জন্য কাজ করে। আমি মনে করি যে একটি সম্ভাব্য সমস্যা হ'ল আপনি "/ ব্যবহারকারীর / জবাব" এ সাবস্ক্রাইব করেছেন এবং আপনি "/ ব্যবহারকারীর / {ব্যবহারকারীর নাম reply / উত্তর" তে বার্তা প্রেরণ করছেন। আমি মনে করি যে আপনার {ব্যবহারকারীর নাম} অংশটি সরিয়ে নেওয়া উচিত এবং রূপান্তরঅ্যান্ডসেন্ডটোসর (স্ট্রিং ব্যবহারকারী, স্ট্রিং গন্তব্য, টি বার্তা) ব্যবহার করা উচিত।
ভিক্টর কে।

ধন্যবাদ তবে আমি চেষ্টা করেছি simpMessagingTemplate.convertAndSendToUser(principal.getName(), "/user/reply", reply);এবং সার্ভার থেকে বার্তা প্রেরণ করা হলে এটি এই ব্যতিক্রম ছুঁড়ে java.lang.IllegalArgumentException: Expected destination pattern "/principal/{userId}/**"
ফেলেছে

@ ভিক্টোরকে সঠিক, এবং আপনি সঠিক সমাধানের বেশ কাছাকাছি ছিলেন। ক্লায়েন্টের পক্ষে আপনার সাবস্ক্রিপশনটি সঠিক ছিল, আপনাকে কেবল চেষ্টা করতে হবে:convertAndSendToUser(principal.getName(), "/reply", reply);
টিপ-সি

উত্তর:


85

ওহ, client side no need to known about current userসার্ভার আপনার জন্য এটি করবে।

সার্ভারে, কোনও ব্যবহারকারীর কাছে বার্তা প্রেরণের জন্য নিম্নলিখিত উপায় ব্যবহার করে:

simpMessagingTemplate.convertAndSendToUser(username, "/queue/reply", message);

দ্রষ্টব্য: ব্যবহার queue, না topic, স্প্রিং সবসময় ব্যবহার queueকরেsendToUser

ক্লায়েন্ট পক্ষ

stompClient.subscribe("/user/queue/reply", handler);

ব্যাখ্যা করা

যখন কোনও ওয়েবসকেট সংযোগ খোলা থাকে, তখন স্প্রিং এটিকে একটি বরাদ্দ করে session id(নয় HttpSession, সংযোগ প্রতি নির্ধারিত)। এবং যখন আপনার ক্লায়েন্ট সাবস্ক্রাইব করে কোনও চ্যানেলের সাথে শুরু হয় /user/, যেমন:, /user/queue/replyআপনার সার্ভার উদাহরণটি একটি সারিতে সাবস্ক্রাইব করবেqueue/reply-user[session id]

ব্যবহারকারীর কাছে বার্তা প্রেরণ ব্যবহার করার সময়, যেমন: ব্যবহারকারীর নামটি admin আপনি লিখবেন writesimpMessagingTemplate.convertAndSendToUser("admin", "/queue/reply", message);

কোনটি session idব্যবহারকারীকে ম্যাপ করা হয়েছে তা বসন্ত নির্ধারণ করবে admin। উদাহরণ: এটা দুই সেশন পাওয়া wsxedc123এবং thnujm456, স্প্রিং এটি 2 গন্তব্যে অনুবাদ করবে queue/reply-userwsxedc123এবং queue/reply-userthnujm456, এবং এটি আপনার বার্তা দালাল 2 গন্তব্যস্থল সঙ্গে আপনার বার্তা পাঠান।

বার্তা ব্রোকার বার্তাগুলি গ্রহণ করে এবং এটি আপনার সার্ভারে পুনরায় সরবরাহ করে যে প্রতিটি সেশনের সাথে সম্পর্কিত অধিবেশন অধিবেশন (ওয়েবস্কট সেশনগুলি এক বা একাধিক সার্ভার ধরে রাখতে পারে)। বসন্ত বার্তাটি destination(যেমন user/queue/reply:) এবং session id(যেমন :) তে অনুবাদ করবে wsxedc123। তারপরে, এটি সম্পর্কিত বার্তাটি প্রেরণ করেWebsocket session


7
আপনি দয়া করে কীভাবে আপনি ব্যবহারকারীর নাম জানেন তা ব্যাখ্যা করতে পারেন? আপনার উদাহরণে আপনি বলেছিলেন যে ব্যবহারকারীর নাম 'অ্যাডমিন', আপনি ব্যবহারকারীর কাছ থেকে ব্যবহারকারীর নাম পান?
জর্জ

4
HttpSessionওয়েবসকেট সংযোগের সূচনা করার সময় থেকে ব্যবহারকারীর নাম পাওয়া গেছে
থানহ এনগুইন ভ্যান

4
দয়া করে আপনি কীভাবে ব্যবহারকারীর নামটি সেট করবেন সে সম্পর্কে আরও তথ্য দিতে পারেন? সেখানে কি আমি সুস্পষ্টর বার্তায় ব্যবহারকারীর নামটি পাঠাতে পারি?
আন্দ্রেস

4
@ এন্ড্রেস: আপনি DefaultHandshakeHandlerপদ্ধতিটিকে প্রসারিত ও ওভাররাইড করতে পারেনdetermineUser
থানহ

4
আপনার ব্যাখ্যা দুর্দান্ত কাজ করে। তবে queue/reply-user[session id]সরকারী নথিতে অংশটি কোথায় ?
hbrls

35

আহ আমি আমার সমস্যা ছিল কি খুঁজে পেয়েছি। প্রথমে আমি /userসাধারণ ব্রোকারের উপসর্গটি নিবন্ধ করিনি

<websocket:simple-broker prefix="/topic,/user" />

তারপরে /userপাঠানোর সময় আমার অতিরিক্ত উপসর্গের দরকার নেই :

convertAndSendToUser(principal.getName(), "/reply", reply);

বসন্তটি স্বয়ংক্রিয়ভাবে "/user/" + principal.getName()গন্তব্যে পৌঁছে যাবে , সুতরাং এটি "/ ব্যবহারকারী / বব / উত্তর" এর মধ্যে সমাধান হয়।

এর অর্থ জাভাস্ক্রিপ্টেও আমি প্রতি ব্যবহারকারীর বিভিন্ন ঠিকানায় সাবস্ক্রাইব করতে হয়েছিল

stompClient.subscribe('/user/' + userName + '/reply,...) 

4
মিম ... ব্যবহারকারীর নাম ক্লায়েন্ট-সাইড সেটআপ করা এড়াতে কি উপায় আছে? সেই মানটি পরিবর্তন করে (উদাহরণস্বরূপ অন্য ব্যবহারকারী নাম ব্যবহার করে) আপনি অন্যের বার্তা দেখতে সক্ষম হবেন।
vdenotaris

4
আমার সমাধান দেখুন: stackoverflow.com/questions/25646671/...
vdenotaris


আরে আমার বন্ধু তুমি কি আমাকে বলতে পার? এই "ব্যবহারকারী" যাইহোক কি? আমি স্প্রিং সিকিউরিটি ব্যবহার করছি এবং আমার ব্যবহারকারীরা (ব্যবহারকারীর নাম) ইমেল ঠিকানা। প্রতিটি ব্যবহারকারী লগ ইন করলে সে তার স্প্রিং সিকিউরিটিতে JWT টোকেন পায়।
ফ্রান্সিসকো সৌজা

আপনার উত্তরে আসার কয়েক ঘন্টা আগেও আমি একই সমস্যার মুখোমুখি হয়েছি। শুধুমাত্র আপনার অন্বেষণ আমাকে সাহায্য করেছে। তোমাকে অনেক ধন্যবাদ!!
নবানীথ

3

আমি STOMP ব্যবহার করে একটি নমুনা ওয়েবসকেট প্রকল্পও তৈরি করেছি। যা আমি লক্ষ্য করছি তা হ'ল

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic", "/queue");// including /user also works
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/getfeeds").withSockJS();
}

}

এটি "/ ব্যবহারকারীর" কনফিগ.এনেবলসিম্পলব্রোকার (... ...


2

থান এনগুইন ভ্যানের সেরা ব্যাখ্যার উপর ভিত্তি করে আমার এটির সমাধান, তবে আমি বার্তা ব্রোকাররেজিস্ট্রিটি কনফিগার করেছি:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/queue/", "/topic/");
        ...
    }
    ...
}

2

হুবহু আমিও একই কাজ করেছি এবং এটি ব্যবহারকারীকে ব্যবহার না করেই কাজ করছে

@Configuration
@EnableWebSocketMessageBroker  
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
       registry.addEndpoint("/gs-guide-websocket").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic" , "/queue");
        config.setApplicationDestinationPrefixes("/app");
    }
}

আরে, আপনি /appকখন এটি ব্যবহার করেন ? কোন ক্ষেত্রে?
ফ্রান্সিসকো সৌজা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.