Chat: Basic send and receive messages.

This commit is contained in:
2015-05-27 01:23:31 +02:00
parent 58824eea58
commit a09af4b1fa
5 changed files with 272 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace Scrummer.Code.Controls
{
public class ChatControl : Control
{
private int _idBoard = 0;
public int IDBoard
{
get { return _idBoard; }
set { _idBoard = value; }
}
public ChatControl()
{
Init += ChatControl_Init;
}
void ChatControl_Init(object sender, EventArgs e)
{
var divChat = new Panel { ID = "divChat", CssClass = "divChat" };
Controls.Add(divChat);
var hidIDMessage = new HiddenField { ID = "hidIDMessage", Value = "0" };
Controls.Add(hidIDMessage);
var txtText = new TextBox { ID = "txtText", CssClass = "chatTextBox" };
Controls.Add(txtText);
var btnSend = new Button { ID = "btnSend", Text = "Send", CssClass = "chatButton" };
Controls.Add(btnSend);
btnSend.Attributes.Add("onclick", String.Format("SendChat('{0}',{1}); return false;", txtText.ClientID, _idBoard));
LiteralControl litScript = new LiteralControl();
litScript.Text = String.Format("<script>RunChat('{0}',{1},'{2}');</script>",
divChat.ClientID, _idBoard, hidIDMessage.ClientID);
Controls.Add(litScript);
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using Scrummer.Code.JSON;
namespace Scrummer.Code
{
public class Message
{
public int IDMessage { get; set; }
public string UserName { get; set; }
public string Text { get; set; }
};
public class MessageBoard
{
private List<Message> _messages = new List<Message>();
private int lastIDMessage = 0;
public List<Message> Messages_GetList(int idMessage)
{
List<Message> listMessages = new List<Message>();
for (int i = 0, n = _messages.Count; i < n; i++)
{
Message msg = _messages[i];
if (msg.IDMessage > idMessage)
{
listMessages.Insert(0, msg);
}
else
{
break;
}
}
return listMessages;
}
public void Message_Add(string userName, string text)
{
lastIDMessage++;
Message msg = new Message();
msg.IDMessage = lastIDMessage;
msg.UserName = userName;
msg.Text = text;
_messages.Insert(0, msg);
}
}
public class ChatHandler : IHttpHandler
{
private static object _monitor = new object();
private static Dictionary<int, MessageBoard> _chatBoards = new Dictionary<int, MessageBoard>();
public bool IsReusable
{
get { throw new NotImplementedException(); }
}
public void ProcessRequest(HttpContext context)
{
if (context.Request.RequestType == "GET")
{
ProcessRevicer(context);
}
if (context.Request.RequestType == "POST")
{
ProcessSender(context);
}
}
private void ProcessRevicer(HttpContext context)
{
int idBoard = Convert.ToInt32(context.Request.Params["idBoard"]);
int idMessage = Convert.ToInt32(context.Request.Params["idMessage"]);
MessageBoard messageBoard;
bool mustWait = true;
do
{
if (_chatBoards.ContainsKey(idBoard))
{
messageBoard = _chatBoards[idBoard];
List<Message> listMessages = messageBoard.Messages_GetList(idMessage);
if (listMessages.Count > 0)
{
mustWait = false;
ResponseObject(context, listMessages);
}
}
if (mustWait)
{
lock (_monitor) { Monitor.Wait(_monitor, 10000); }
}
} while (mustWait);
}
private void ProcessSender(HttpContext context)
{
string strIDBoard = GetRequestParm(context, "idBoard");
int idBoard = Convert.ToInt32(string.IsNullOrEmpty(strIDBoard) ? "0" : strIDBoard);
string userName = Convert.ToString(GetRequestParm(context, "userName"));
string text = Convert.ToString(GetRequestParm(context, "text"));
lock (_chatBoards)
{
MessageBoard messageBoard;
if (_chatBoards.ContainsKey(idBoard))
{
messageBoard = _chatBoards[idBoard];
}
else
{
messageBoard = new MessageBoard();
_chatBoards[idBoard] = messageBoard;
}
messageBoard.Message_Add(userName, text);
lock (_monitor) { Monitor.PulseAll(_monitor); }
}
}
private string GetRequestParm(HttpContext context, string parm)
{
foreach (string key in context.Request.Params.AllKeys)
{
if (string.IsNullOrEmpty(key) == false && key.EndsWith(parm))
{
return context.Request.Params[key];
}
}
return string.Empty;
}
private void ResponseObject(HttpContext context, object obj)
{
var jsonWritter = new JSONWriter(true);
context.Response.ContentType = "text/json";
context.Response.Write(jsonWritter.Write(obj));
}
}
}

View File

@@ -0,0 +1,75 @@
function RunChat(divContainer, idBoard, hidIDMessage) {
divContainer = GetElement(divContainer);
hidIDMessage = GetElement(hidIDMessage);
var CreateMessageDOM = function (message) {
var divMessageRow = document.createElement("DIV");
divMessageRow.className = "messageRow";
var divMessage = document.createElement("DIV");
divMessage.className = "message";
divMessageRow.appendChild(divMessage);
var divUser = document.createElement("DIV");
divUser.className = "user";
divUser.innerHTML = escapeHTML(message.UserName);
divMessage.appendChild(divUser);
var text = message.Text;
var divText = document.createElement("DIV");
divText.className = "text";
divText.innerHTML = escapeHTML(text);
divMessage.appendChild(divText);
return divMessageRow;
};
var RequestChatData = function () {
var requestUrl = "ChatHandler?idBoard=" + idBoard + "&idMessage=" + hidIDMessage.value;
var ReciveChatData = function (responseText) {
recvMsgs = JSON.parse(responseText);
if (recvMsgs) {
var idMessage = parseInt(hidIDMessage.value);
for (var i = 0, n = recvMsgs.length; i < n; i++) {
var msg = recvMsgs[i];
if (idMessage < msg.IDMessage) {
hidIDMessage.value = msg.IDMessage;
idMessage = msg.IDMessage;
var elemMessage = CreateMessageDOM(msg);
divContainer.appendChild(elemMessage);
}
}
divContainer.scrollTop = divContainer.scrollHeight;
}
// Reset pool
window.setTimeout(function () {
RequestChatData();
}, 20);
};
var ErrorChatData = function () {
// Retry
window.setTimeout(function () {
RequestChatData();
}, 5000);
};
// Pool data
SendRequest(requestUrl, ReciveChatData, ErrorChatData);
};
RequestChatData();
}
function SendChat(txtText, idBoard) {
txtText = GetElement(txtText);
var data = {
"text": txtText.value,
"idBoard": idBoard,
"userName": "VAR"
};
txtText.value = "";
SendData("ChatHandler", data, null, null);
}

View File

@@ -70,11 +70,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Scripts\02. Ajax.js" /> <Content Include="Scripts\02. Ajax.js" />
<Content Include="Scripts\10. Chat.js" />
<Content Include="Styles\01. base.css" /> <Content Include="Styles\01. base.css" />
<Content Include="Styles\10. Chat.css" />
<Content Include="Web.config" /> <Content Include="Web.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Code\Bundler.cs" /> <Compile Include="Code\Bundler.cs" />
<Compile Include="Code\Controls\ChatControl.cs" />
<Compile Include="Code\Controls\ChatHandler.cs" />
<Compile Include="Code\Controls\CLabel.cs" /> <Compile Include="Code\Controls\CLabel.cs" />
<Compile Include="Code\GlobalErrorHandler.cs" /> <Compile Include="Code\GlobalErrorHandler.cs" />
<Compile Include="Code\JSON\ParserContext.cs" /> <Compile Include="Code\JSON\ParserContext.cs" />

View File

@@ -0,0 +1,4 @@
.divChat {
overflow: auto;
height: 300px;
}