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.
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)
{
...
}
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With