简体   繁体   English

信号器:当用户向特定用户发送消息时,无法发回消息

[英]Signalr: Cannot send message back when user send message for specific user

I am new in using SignalR . 我是使用SignalR When I send a message to a particular user are: 当我向特定用户发送消息时:

  1. I do not get the message back (I do not see it on the screen). 我没有收到该消息(我在屏幕上看不到它)。
  2. The user receives a notice can not send a message back. 用户收到通知无法发送回消息。

That means sending a message can only be in one direction. 这意味着发送消息只能在一个方向上进行。 How to do that two users can send messages to each other?** 两个用户如何互相发送消息?**

There is my classes i use: 我使用的是我的课程:

[HubName("TSChatHub")]
[Authorize]
public class ChatHub : Hub
{

    private readonly static ConnectionMapping<string> _connections =
        new ConnectionMapping<string>();

    public void SendChatMessage(string who, string message)
    {
        string name = Context.User.Identity.Name;

        foreach (var connectionId in _connections.GetConnections(who))
        {
            Clients.Client(connectionId).addChatMessage(name + ": " + message);
        }
    }

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

        _connections.Add(name, Context.ConnectionId);

        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        string name = Context.User.Identity.Name;

        _connections.Remove(name, Context.ConnectionId);

        return base.OnDisconnected(stopCalled);
    }

    public override Task OnReconnected()
    {
        string name = Context.User.Identity.Name;

        if (!_connections.GetConnections(name).Contains(Context.ConnectionId))
        {
            _connections.Add(name, Context.ConnectionId);
        }

        return base.OnReconnected();
    }
}

  public class ConnectionMapping<T>
{
    private readonly Dictionary<T, HashSet<string>> _connections =
       new Dictionary<T, HashSet<string>>();

    public int Count
    {
        get
        {
            return _connections.Count;
        }
    }

    public void Add(T key, string connectionId)
    {
        lock (_connections)
        {
            HashSet<string> connections;
            if (!_connections.TryGetValue(key, out connections))
            {
                connections = new HashSet<string>();
                _connections.Add(key, connections);
            }

            lock (connections)
            {
                connections.Add(connectionId);
            }
        }
    }

    public IEnumerable<string> GetConnections(T key)
    {
        HashSet<string> connections;
        if (_connections.TryGetValue(key, out connections))
        {
            return connections;
        }

        return Enumerable.Empty<string>();
    }

    public void Remove(T key, string connectionId)
    {
        lock (_connections)
        {
            HashSet<string> connections;
            if (!_connections.TryGetValue(key, out connections))
            {
                return;
            }

            lock (connections)
            {
                connections.Remove(connectionId);

                if (connections.Count == 0)
                {
                    _connections.Remove(key);
                }
            }
        }
    }
}

There is my View: 我的看法是:

  <div class="chatcontainer">
    <input type="text" id="message" />
    <input type="button" id="sendmessage" value="Send" />
    <input type="hidden" id="displayname" />
    <ul id="discussion">
    </ul>
</div>

 $(function () {
        // Declare a proxy to reference the hub. 
        var chat = $.connection.TSChatHub;
        debugger;
        // Create a function that the hub can call to broadcast messages.
        chat.client.addChatMessage = function (name, message) {
            // Add the message to the page. 
            $('#discussion').append('<li><strong>' + htmlEncode(name)
                + '</strong>:&nbsp;&nbsp;' + htmlEncode(name) + '</li>');
        };
        // Get the user name and store it to prepend to messages.
       // $('#displayname').val(prompt('Enter your name:', ''));
        // Set initial focus to message input box.  
        $('#message').focus();
        // Start the connection.
        $.connection.hub.start().done(function () {
            console.log('Now connected, connection ID=' + $.connection.hub.id);
            $('#sendmessage').click(function () {
                // Call the Send method on the hub. 
                chat.server.sendChatMessage($('#message').val());
                // Clear text box and reset focus for next comment. 
                $('#message').val('').focus();
            });
        }).fail(function () { console.log("Could not connect"); });
    });

 // This optional function html-encodes messages for display in the page.
    function htmlEncode(value) {
        var encodedValue = $('<div />').text(value).html();
        return encodedValue;
    }

Anyone has a solution to help me 任何人都有解决方案可以帮助我

If I correctly understand you, you can send a message to specific user like this. 如果我理解正确,您可以像这样向特定用户发送消息。

public void SendChatMessage(string who, string message)
{
    string name = Context.User.Identity.Name;

    //foreach (var connectionId in _connections.GetConnections(who))
    //{
        //Clients.Client(connectionId).addChatMessage(name + ": " + message);
    //}
    Clients.User(who).addChatMessage(name + ": " + message);
}

And "string who" should be receiver user username. 并且“ string who”应该是接收者用户的用户名。 Hope this help. 希望对您有所帮助。

Just change your the arguments of your addChatMessage method 只需更改您的addChatMessage方法的参数addChatMessage

 public void SendChatMessage(string who, string message)
    {
        string name = Context.User.Identity.Name;

        foreach (var connectionId in _connections.GetConnections(who))
        {
            Clients.Client(connectionId).addChatMessage(name , message);
        }
    }

This line of code is calling your client side addChatMessage method that you have written on the View 此行代码调用您在View上编写的客户端addChatMessage方法

Clients.Client(connectionId).addChatMessage(name , message);

The function was not getting mapped properly since the argument you were supplying from your cs page was different than expected by the client side method. 该函数未正确映射,因为您从CS页面提供的参数与客户端方法预期的不同。

Your call 您的来电

 Clients.Client(connectionId).addChatMessage(name + ": " + message);

params expected by client method 客户方法期望的参数

 chat.client.addChatMessage = function (name, message) 

you were supplying a single argument hence it was not getting mapped. 您只提供了一个参数,因此没有被映射。

If still the problem persists try to check _connections dictionary in the SendChatMessage method the only reason a message will not come back to you is if your connection id is not added to this dictionary which is not possible since that is the first step that happens as soon as you run the app in the OnConnected event 如果问题仍然存在,请尝试在SendChatMessage方法中检查_connections词典,消息不会返回的唯一原因是您的连接ID未添加到此词典中,这是不可能的,因为这是第一步在OnConnected事件中运行应用程序时

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM