3

I am new in SignalR and I am trying to develop simple chat application using signalR with ASP.NET MVC 3. I have done following coding with Tutorial: Getting Started with SignalR (C#) reference.

ChatHub

public class ChatHub : Hub
{
    private static readonly Dictionary<string, ChatUser> _users 
        = new Dictionary<string, ChatUser>(StringComparer.OrdinalIgnoreCase);

    public Task Send(string message)
    {
        var user = _users.Values.FirstOrDefault(u => u.ClientId == Context.ConnectionId);

        if (user == null)
        {
            throw new Exception("User is not logged in");
        }

         return Clients.All.message(user.Name, message, TimeStamp());
    }

    public void Logon(string clientName)
    {
        if (clientName.Length > 10)
        {
            throw new Exception("I prefer short names.");
        }

        if (_users.Any(x => x.Key == clientName))
        {
            throw new Exception("User name is already taken, please select a different one.");
        }

        _users.Add(clientName, new ChatUser { ClientId = Context.ConnectionId, Name = clientName });

        Clients.Caller.name = clientName;

        Clients.All.loggedOn(clientName, TimeStamp());
    }

    public Task Logout()
    {
        var user = _users.Values.FirstOrDefault(u => u.ClientId == Context.ConnectionId);

        if (user != null)
        {
            _users.Remove(user.Name);
           return  Clients.All.loggedOff(user.Name, TimeStamp());
        }

        return null;
    }



    public IEnumerable<ChatUser> GetUsers()
    {
        return _users.Values.OrderBy(x => x.Name);
    }

    private static string TimeStamp()
    {
        return DateTime.Now.ToShortTimeString();
    }
}

ChatUser Class

public class ChatUser
{
    public string ClientId { get; set; }
    public string Name { get; set; }
}

IndexView.chtml

SignalR Chat

        <div id="info" class="round">
            <h1>
                SignalR Chat</h1>
            <form id="startform">
             Enter your name:
            <input type="text" id="name" />
            <input type="button" id="btn_login" class="button" style="margin-top: 25px;" value="Start chatting" />
            </form>
            <div id="login_error" style="margin-top: 100px;" class="error">
            </div>
        </div>

        <div id="chat">
            <div style="height: 50px;">
                <div>SignalRChat</div>
                <div id="logout">
                    <a href="" id="btn_logout">Logout</a>
                </div>
            </div>
            <div class="users-box right round2">
                <strong>Users in chat:</strong>
                <ul id="users">
                </ul>
            </div>
            <div class="chat-box round2">
                <div id="messages">
                    <ul id="message-list">
                    </ul>
                </div>
                <form id="chatform">
                <table width="100%">
                    <tr>
                        <td>
                            <input type="text" id="msg" />
                        </td>
                        <td align="right" width="100px">
                            <input type="button" id="btn_send" class="button" value="Send" />
                        </td>
                    </tr>
                </table>
                </form>
            </div>
        </div>
    </div>
</div>


 <!--Add script to update the page and send messages.--> 
<script type="text/javascript">
    $(function () {
         var onlineUsers = null;
        var userList = [];
        var chat = $.connection.chatHub;

        var getUsers = function () {
            chat.server.getUsers().done(function (users) {
                onlineUsers = users;
                updateUserList();
            });
        };

        var updateUserList = function () {
            $('#users li').remove();
            userList = [];

            $.each(onlineUsers, function () {
                var listItem = $('<li>{0}</li>'.format(this.Name));
                $('#users').append(listItem);

                userList[this.Name] = User(this.Name, listItem);
            });
        };

        var send = function () {
            if ($('#msg').val() !== '') {
                chat.server.Send($('#msg').val());
                $("#msg").val('');
            }
        };

        var login = function () {
            if ($('#name').val() !== '') {
                clientName = $('#name').val();

                chat.server.Logon(clientName, function () {
                    $("#info").toggle();
                    $("#chat").toggle();
                    $('#msg').focus();
                    getUsers();
                }).fail(function (e) {
                    $('#login_error').html(e);
                });
            }
        };

        var logout = function () {
            chat.server.Logout();
        }

        // Callbacks from server
        chat.client.message = function (user, msg, time) {
            $('#message-list').append('<li class="message">{0} {1}: {2}</li>'.format(time, user, msg));
            $("#messages").prop({ scrollTop: $("#messages").prop("scrollHeight") });
        };

        chat.client.loggedOn = function (user, time) {
            $('#message-list').append('<li class="info">{0} {1} logged on</li>'.format(time, user));
            getUsers();
        };

        chat.client.loggedOff = function (user, time) {
            $('#message-list').append('<li class="info">{0} {1} logged off</li>'.format(time, user));
            getUsers();
        };

        chat.client.userTyping = function (user) {
            userList[user].typing();
        };

        // Form events
        $("#btn_send").click(function () { send(); $('#msg').focus(); });
        $("#btn_login").click(function () { login(); });
        $("#btn_logout").click(function () { logout(); });
        $('#chatform').submit(function () { send(); return false; });
        $('#startform').submit(function () { login(); return false; });


        // Logout when user closes browser
        window.onbeforeunload = function () { chat.server.Logout(); };

        // Start chat
        $.connection.hub.start().done(function () {
            alert("Connected");
        });

        $("#chat").toggle();
        $('#name').focus();

    });

</script>

But I am getting following when I am trying to call Logon method of ChatHub:

Uncaught TypeError: Object # has no method 'Logon'

Anyone help me where I am wrong in above coding with SignalR.


When communicating with server methods via JavaScript with SignalR the server methods are referenced as Camel Cased unless specified via the HubMethodName attribute.

If you want to continue using your current code you can fix it in two ways.

  1. On your server side Hub put [HubMethodName("foo")] above each method with the correct name. So Logon would be:

    [HubMethodName("Logon")] public void Logon(string clientName) { ... }

  2. in the JavaScript script you can do:

    chat.server.logon(...);

Keep in mind you'd have to apply either one of these approaches to all methods (via #1) or all communications to the server (via #2).

Hope this helps!

4

1 回答 1

2

当使用 SignalR 通过 JavaScript 与服务器方法通信时,除非通过HubMethodName属性指定,否则服务器方法被引用为 Camel Cased。

如果您想继续使用当前代码,您可以通过两种方式修复它。

  1. 在您的服务器端集线器上[HubMethodName("foo")],使用正确的名称放置在每个方法之上。所以登录将是:

    [HubMethodName("Logon")] public void Logon(string clientName) { ... }

  2. 在 JavaScript 脚本中,您可以执行以下操作:

    chat.server.logon(...);

请记住,您必须将这些方法中的任何一种应用于所有方法(通过#1)或与服务器的所有通信(通过#2)。

希望这可以帮助!

于 2012-12-19T17:50:39.590 回答