Chat: Basic send and receive messages.
This commit is contained in:
48
Scrummer/Code/Controls/ChatControl.cs
Normal file
48
Scrummer/Code/Controls/ChatControl.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
141
Scrummer/Code/Controls/ChatHandler.cs
Normal file
141
Scrummer/Code/Controls/ChatHandler.cs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
Scrummer/Scripts/10. Chat.js
Normal file
75
Scrummer/Scripts/10. Chat.js
Normal 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);
|
||||||
|
}
|
||||||
@@ -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" />
|
||||||
|
|||||||
4
Scrummer/Styles/10. Chat.css
Normal file
4
Scrummer/Styles/10. Chat.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.divChat {
|
||||||
|
overflow: auto;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user