Last active
December 24, 2015 14:49
-
-
Save codeplanner/6815648 to your computer and use it in GitHub Desktop.
A simple chat where you can select one or more clients to recieve the message... The run the sample:
1 - Create a new project in Visual Studio (I used MVC4) 2 - Install XSockets from nuget 3 - Add the chat.cs file below 4 - Add the chat.html file below 5 - Go to project properties and set project to run under Visual Studio Development Server 6 -…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using XSockets.Core.Common.Socket.Event.Attributes; | |
using XSockets.Core.XSocket; | |
using XSockets.Core.XSocket.Helpers; | |
namespace SimpleChat | |
{ | |
/// <summary> | |
/// A model for easier model bidning when sending messages | |
/// </summary> | |
public class ChatMessage | |
{ | |
public string UserName { get; set; } | |
public string Time { get; set; } | |
public string Message { get; set; } | |
} | |
/// <summary> | |
/// The userinfo... Makes more sense to also have a name on the user | |
/// </summary> | |
public class User | |
{ | |
public Guid Id { get; set; } | |
public string UserName { get; set; } | |
} | |
/// <summary> | |
/// A custom plugin (controller) in XSockets | |
/// This one for a simple chat where you can select who to target... | |
/// </summary> | |
public class Chat : XSocketController | |
{ | |
/// <summary> | |
/// The user for this controller. | |
/// The NoEvent prevent the property from being changed from JavaScript directly | |
/// </summary> | |
[NoEvent] | |
public User User { get; set; } | |
/// <summary> | |
/// Ctor - listen for the disconnect event | |
/// </summary> | |
public Chat() | |
{ | |
this.OnClientDisConnect += Chat_OnClientDisConnect; | |
} | |
void Chat_OnClientDisConnect(object sender, XSockets.Core.Common.Socket.Event.Arguments.OnClientDisConnectArgs e) | |
{ | |
//Tell all clients that I leave | |
this.SendToAllExceptMe(this.User,"onClientDisconnected"); | |
} | |
/// <summary> | |
/// Send a message to the clients having their ClientGuid in the clients list | |
/// </summary> | |
/// <param name="message"></param> | |
/// <param name="clients"></param> | |
public void OnChatMessage(string message, List<Guid> clients) | |
{ | |
//Create a chatmessage | |
var chatMessage = new ChatMessage | |
{ | |
UserName = this.User.UserName, | |
Message = message, | |
Time = DateTime.Now.ToLongTimeString() | |
}; | |
//If you want to always send to the sender as well... uncomment this... | |
//if(!clients.Contains(this.ClientGuid)) | |
// clients.Add(this.ClientGuid); | |
//send the message to the clients in the list provided | |
this.SendTo(p => clients.Contains(p.ClientGuid), chatMessage,"onChatMessage"); | |
} | |
/// <summary> | |
/// Set the username for the client and notify others that I am online | |
/// </summary> | |
/// <param name="userName"></param> | |
public void SetUserName(string userName) | |
{ | |
//Set the username | |
this.User = new User{ Id = this.ClientGuid, UserName = userName}; | |
//Tell others that the user is online | |
this.SendToAllExceptMe(this.User, "onClientConnected"); | |
//Send all other clients to me, but only clients that have set a username | |
this.Send(this.Find(p => p.User != null).Select(p => p.User),"onClientList"); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title></title> | |
<script src="Scripts/jquery-1.9.1.js"></script> | |
<script src="Scripts/XSockets.latest.js"></script> | |
<script src="Scripts/knockout-2.3.0.js"></script> | |
<style> | |
select { min-width: 150px;} | |
input { min-width: 150px;} | |
</style> | |
<script> | |
var ChatViewModel = { | |
me: ko.observable(''), | |
messages: ko.observableArray([]), | |
users: ko.observableArray([]), | |
userRemove: function (user) { | |
console.log('userremove ',user); | |
var match = ko.utils.arrayFirst(ChatViewModel.users(), function (u) { | |
return u.Id === user.Id; | |
}); | |
if (match) { | |
ChatViewModel.users.remove(match); | |
} | |
} | |
}; | |
var conn = null; | |
$(function () { | |
//Hide the chat when we start... | |
$('#chat').hide(); | |
//Bind knockout | |
ko.applyBindings(ChatViewModel); | |
//Connect to our custom Chat Controller... | |
conn = new XSockets.WebSocket('ws://127.0.0.1:4502/Chat'); | |
//When the open event is fired... | |
conn.on(XSockets.Events.open, function (clientInfo) { | |
console.log('Connected to Chat', clientInfo); | |
//Bind to our custom event... called chatMessage | |
conn.on('onChatMessage', function (data) { | |
//Prepend to chat... | |
ChatViewModel.messages.unshift(data); | |
}); | |
//When we get the list of clients... | |
conn.on('onClientList', function (clients) { | |
ChatViewModel.users(clients); | |
}); | |
//listen for new clients | |
conn.on('onClientConnected', function (client) { | |
ChatViewModel.users.push(client); | |
}); | |
//listen for clients that leave | |
conn.on('onClientDisconnected', function (client) { | |
ChatViewModel.userRemove(client); | |
}); | |
}); | |
//UI Events | |
//When the user click join button... Open websocket | |
$('#btn-join').on('click', function () { | |
var userName = $('#input-username').val().trim(); | |
if (userName.length === 0) { | |
alert("You have to provide a username"); | |
return; | |
} | |
//Set the username | |
conn.publish('setUserName', { userName: userName }); | |
ChatViewModel.me(userName); | |
//Show the chat | |
$('#join').hide(); | |
$('#chat').show(); | |
}); | |
//Send a message to the client(s) selected | |
$('#btn-send').on('click', function () { | |
var message = $('#input-message').val().trim(); | |
if (message.length === 0) { | |
alert("You have to provide a message"); | |
return; | |
} | |
var clients = $('#select-clients').val(); | |
if (clients === null) { | |
alert("You have not selected any client(s) to send to"); | |
return; | |
} | |
//Send the message written and include the clients selected | |
conn.publish('onChatMessage', { message: message, clients: clients}); | |
}); | |
}); | |
</script> | |
</head> | |
<body> | |
<div id="join"> | |
<input id="input-username" placeholder="Write username here..." /> | |
<button id="btn-join">Join Chat</button> | |
</div> | |
<div id="chat"> | |
<h3 data-bind="text:me"></h3> | |
<div> | |
<h4>Select all clients in the multiselect-list that should get the message</h4> | |
<select multiple="multiple" id="select-clients" data-bind="foreach:users"> | |
<option data-bind="value: Id, text: UserName"></option> | |
</select><br/> | |
<input id="input-message" placeholder="Message here..." value="Hello World"/> | |
<button id="btn-send">Send</button> | |
</div> | |
<h3>Messages</h3> | |
<table> | |
<thead> | |
<tr> | |
<td>Time</td> | |
<td>From</td> | |
<td>Message</td> | |
</tr> | |
</thead> | |
<tbody data-bind="foreach: messages"> | |
<tr> | |
<td data-bind="text:Time"></td> | |
<td data-bind="text:UserName"></td> | |
<td data-bind="text:Message"></td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment