सिग्नलआर - एक विशिष्ट उपयोगकर्ता को संदेश भेजना (IUserIdProvider) * NEW 2.0.0 * का उपयोग करना


101

Asp.Net SignalR के नवीनतम संस्करण में, इंटरफ़ेस "IUserIdProvider" का उपयोग करके, एक विशिष्ट उपयोगकर्ता को संदेश भेजने का एक नया तरीका जोड़ा गया था।

public interface IUserIdProvider
{
   string GetUserId(IRequest request);
}

public class MyHub : Hub
{
   public void Send(string userId, string message)
   {
      Clients.User(userId).send(message);
   }
}

मेरा प्रश्न है: मुझे कैसे पता चलेगा कि मैं किसको अपना संदेश भेज रहा हूँ? इस नई पद्धति की व्याख्या बहुत ही सतही है। और इस बग के साथ सिग्नलआर 2.0.0 का मसौदा विवरण और संकलन नहीं करता है। क्या किसी ने इस सुविधा को लागू किया है?

अधिक जानकारी: http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider

हग्स।


1
आपको SignalR के साथ प्रमाणीकरण और प्राधिकरण देखने की आवश्यकता है। UserId IPrincipal प्रदाता का हिस्सा होगा।
गजनोह

जवाबों:


153

सिग्नलआर प्रत्येक कनेक्शन के लिए ConnectionId प्रदान करता है। यह पता लगाने के लिए कि किस कनेक्शन का संबंध किससे (उपयोगकर्ता) है, हमें कनेक्शन और उपयोगकर्ता के बीच एक मैपिंग बनाने की आवश्यकता है। यह इस बात पर निर्भर करता है कि आप अपने एप्लिकेशन में किसी उपयोगकर्ता की पहचान कैसे करते हैं।

सिग्नलआर 2.0 में, यह इनबिल्ट का उपयोग करके किया जाता है IPrincipal.Identity.Name, जो एएसपी.नेट प्रमाणीकरण के दौरान सेट किए गए उपयोगकर्ता पहचानकर्ता में लॉग होता है।

हालाँकि, आपको पहचानकर्ता का उपयोग करने के बजाय किसी भिन्न पहचानकर्ता का उपयोग करके उपयोगकर्ता के साथ कनेक्शन मैप करना पड़ सकता है। इस प्रयोजन के लिए इस नए प्रदाता को कनेक्शन के साथ उपयोगकर्ता को मैप करने के लिए आपके कस्टम कार्यान्वयन के साथ उपयोग किया जा सकता है।

मैपिंग सिग्नलआर का उदाहरण IUserIdProvider का उपयोग करने वाले कनेक्शनों के लिए

मान लें कि हमारा एप्लिकेशन userIdप्रत्येक उपयोगकर्ता की पहचान करने के लिए एक का उपयोग करता है । अब, हमें एक विशिष्ट उपयोगकर्ता को संदेश भेजने की आवश्यकता है। हमारे पास userIdऔर है message, लेकिन सिग्नलआर को हमारे उपयोगकर्ता आईडी और कनेक्शन के बीच मैपिंग भी पता होना चाहिए।

इसे प्राप्त करने के लिए, पहले हमें एक नया वर्ग बनाने की आवश्यकता है, जो लागू होता है IUserIdProvider:

public class CustomUserIdProvider : IUserIdProvider
{
     public string GetUserId(IRequest request)
    {
        // your logic to fetch a user identifier goes here.

        // for example:

        var userId = MyCustomUserClass.FindUserId(request.User.Identity.Name);
        return userId.ToString();
    }
}

दूसरा कदम सिग्नल CustomUserIdProviderकार्यान्वयन को डिफ़ॉल्ट कार्यान्वयन के बजाय हमारे उपयोग के लिए बताना है । हब कॉन्फ़िगरेशन को प्रारंभ करते समय स्टार्टअप्स में यह किया जा सकता है:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var idProvider = new CustomUserIdProvider();

        GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);          

        // Any connection or hub wire up and configuration should go here
        app.MapSignalR();
    }
}

अब, आप किसी विशिष्ट उपयोगकर्ता को संदेश भेज सकते हैं userId, जैसे कि प्रलेखन में उल्लिखित है, जैसे:

public class MyHub : Hub
{
   public void Send(string userId, string message)
   {
      Clients.User(userId).send(message);
   }
}

उम्मीद है की यह मदद करेगा।


हाय दोस्त, देर से प्रतिक्रिया के लिए खेद है! लेकिन मैंने CustomUserIdProvider बनाने वाली Id का उपयोग करने की कोशिश की, लेकिन "OnConnected" विधि यह समान नहीं है। मैं डेटाबेस में उपयोगकर्ता से कैसे लिंक करूं? धन्यवाद!
इगोर

7
MyCustomUserClass क्या है?
डैनी बुलिस

2
"MyCustomUserClass" आपका कस्टम उपयोगकर्ता वर्ग हो सकता है जिसमें FindUserId विधि शामिल है। यह सिर्फ उदाहरण के लिए है। आपके पास किसी भी वर्ग में कोई भी तरीका हो सकता है जो आपको UserId लौटाए और यहां उसका उपयोग करें।
सुमंत

5
धन्यवाद @ सुमंत, मेरा मुद्दा समाप्त हो रहा है कि b / c मैं एक वेब एपीआई परियोजना में था, जहाँ मैंने OAuth 2 को बियरर टोकन के साथ लागू किया था, मुझे क्वेरी स्ट्रिंग पर बियरर टोकन को पारित करने के लिए तर्क को लागू करना था क्योंकि इसे खींचा नहीं जा सकता था उस प्रारंभिक सिग्नलर के हेडर अनुरोध को कनेक्ट करते हैं। बस अनुरोध का उपयोग नहीं किया जा सका।
User.Identity.Name

1
@ सुमंत मैं पहले ही हल कर चुका हूँ। समस्या यह थी कि मैं app.MapSignalR();प्रमाणीकरण से पहले Global.asax में डाल दिया था ।
मिस्टर रोबोट

38

यहाँ एक शुरुआत है .. सुझाव / सुधार के लिए खोलें।

सर्वर

public class ChatHub : Hub
{
    public void SendChatMessage(string who, string message)
    {
        string name = Context.User.Identity.Name;
        Clients.Group(name).addChatMessage(name, message);
        Clients.Group("2@2.com").addChatMessage(name, message);
    }

    public override Task OnConnected()
    {
        string name = Context.User.Identity.Name;
        Groups.Add(Context.ConnectionId, name);

        return base.OnConnected();
    }
}

जावास्क्रिप्ट

(ध्यान दें कि ऊपर दिए गए सर्वर कोड में कैसे addChatMessageऔर sendChatMessageक्या तरीके हैं)

    $(function () {
    // Declare a proxy to reference the hub.
    var chat = $.connection.chatHub;
    // Create a function that the hub can call to broadcast messages.
    chat.client.addChatMessage = function (who, message) {
        // Html encode display name and message.
        var encodedName = $('<div />').text(who).html();
        var encodedMsg = $('<div />').text(message).html();
        // Add the message to the page.
        $('#chat').append('<li><strong>' + encodedName
            + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        $('#sendmessage').click(function () {
            // Call the Send method on the hub.
            chat.server.sendChatMessage($('#displayname').val(), $('#message').val());
            // Clear text box and reset focus for next comment.
            $('#message').val('').focus();
        });
    });
});

परिक्षण यहां छवि विवरण दर्ज करें


हाय दोस्त, देर से प्रतिक्रिया के लिए खेद है! लेकिन मैं CONNECTIONID के नुकसान को कैसे रोक सकता हूँ? धन्यवाद।
इगोर

5
@lgao मुझे कोई पता नहीं है।
मफिन मैन

इस पंक्ति की आवश्यकता क्यों थी --- Clients.Group ("2@2.com")। addChatMessage (नाम, संदेश); ??
थॉमस

@ थोमस मैंने संभवतः इसे डेमो के लिए शामिल किया था। किसी विशिष्ट समूह को प्रसारित करने का एक और तरीका होना चाहिए क्योंकि यह हार्डकोड था।
मफिन मैन

इस सरल समाधान ने एक विशिष्ट लॉग इन उपयोगकर्ता को संदेश भेजने के लिए मेरी समस्या को हल किया। इसका सरल, तेज और समझने में आसान है। अगर मैं कर सकता तो मैं इस उत्तर को कई बार बढ़ा देता।
राफेल AMS

5

यह है कि किसी विशिष्ट उपयोगकर्ता (किसी प्रदाता का उपयोग किए बिना) को लक्षित करने के लिए साइनार का उपयोग कैसे करें:

 private static ConcurrentDictionary<string, string> clients = new ConcurrentDictionary<string, string>();

 public string Login(string username)
 {
     clients.TryAdd(Context.ConnectionId, username);            
     return username;
 }

// The variable 'contextIdClient' is equal to Context.ConnectionId of the user, 
// once logged in. You have to store that 'id' inside a dictionaty for example.  
Clients.Client(contextIdClient).send("Hello!");

2
कैसे अपने इस का उपयोग कर रहे contextIdClientहैं इसे पाने के लिए :(
नव

2

पर देखो SignalR टेस्ट की सुविधा के लिए।

टेस्ट "SendToUser" एक नियमित ओवेन प्रमाणीकरण पुस्तकालय का उपयोग करके स्वचालित रूप से पारित उपयोगकर्ता की पहचान लेता है।

परिदृश्य आपके पास एक उपयोगकर्ता है जो कई उपकरणों / ब्राउज़रों से जुड़ा हुआ है और आप उसके सभी सक्रिय कनेक्शनों को संदेश भेजना चाहते हैं।


धन्यवाद दोस्त! लेकिन प्रोजेक्ट संस्करण 2.0 यहां सिग्नलआर को संकलित नहीं कर रहा है। : (; दुर्भाग्य से मैं इस तक नहीं पहुँच सकता।
इगोर

0

पुराना धागा, लेकिन अभी यह एक नमूने में आया है:

services.AddSignalR()
            .AddAzureSignalR(options =>
        {
            options.ClaimsProvider = context => new[]
            {
                new Claim(ClaimTypes.NameIdentifier, context.Request.Query["username"])
            };
        });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.