I'm sorry maybe I didn't declare my problem well.
I'm trying to create chatting rooms where more than one instant client can entre. And for each client can entre more than one chatting room simultaneously.
It is a simple design two web pages (Default.aspx, CommPage.aspx) and two classes (Groups, ChattingRoom).
1) Default.aspx : my main page I do some DHTML (changes on client-side) so I use JavaScript to do whatever I want.
On page load send a receive-request to CommPage.aspx with group name
- function page_load()
-
{
-
/// on load request for new data
-
receiveData("g1");
-
}
-
function receiveData(group)
-
{
-
if(null==xmlHttpReceiver)
-
{
-
alert("Your browser does not support AJAX!");
-
return;
-
}
-
-
var url="CommPage.aspx";
-
url=url+"?way=receive"+"&group="+group;
-
-
xmlHttpReceiver.onreadystatechange=receiverStateChanged;
-
xmlHttpReceiver.open("GET",url,true);
-
xmlHttpReceiver.send(null);
-
}
-
function receiverStateChanged()
-
{
-
if (xmlHttpReceiver.readyState==4)
-
{
-
document.getElementById("Text2").value = xmlHttpReceiver.responseText + "\r\n";
-
-
/// after receiving request to receive again;
-
/// circulation
-
receiveData("g1");
-
}
-
}
On button click send a send-request to CommPage.aspx with group name and user name and message (all are strings).
- function Button2_onclick() {
-
-
var mess = document.getElementById('Text1').value;
-
document.getElementById("Text1").value="";
-
sendData("g1","u1",mess);
-
}
-
function sendData(group, user, message)
-
{
-
if (message.length==0)
-
{
-
return;
-
}
-
if (xmlHttpSender==null)
-
{
-
alert ("Your browser does not support AJAX!");
-
return;
-
}
-
var url="CommPage.aspx";
-
url=url+"?way=send"+"&message="+message+"&user="+user+"&group="+group;
-
-
xmlHttpSender.onreadystatechange=senderStateChanged;
-
xmlHttpSender.open("GET",url,true); // POST
-
xmlHttpSender.send(null);
-
}
2) CommPage.aspx: executes c# methods.
on Page_Load verify the request either send or receive request
- public partial class Default2 : System.Web.UI.Page
-
{
-
Groups _groups = Groups.Instance;
-
ChatRoom _myRoom;
-
-
protected void Page_Load(object sender, EventArgs e)
-
{
-
Response.Expires = -1;
-
-
if ("receive" == Request.QueryString["way"])
-
ReceiveRequested();
-
else
-
SendRequested();
-
}
-
-
private void SendRequested()
-
{
-
_myRoom = _groups.MyRoom(Request.QueryString["group"]);
-
string groupName = Request.QueryString["group"];
-
string userName = Request.QueryString["user"];
-
string message = Request.QueryString["message"];
-
-
-
//try then catch null reference and redirect to custom error page, so that'll happend only
-
// if this page is requested directly and no parameters are set.
-
-
_myRoom.NewMessageContent = userName + " says :" + message + Environment.NewLine;
-
Thread writer = new Thread(new ThreadStart(Write));
-
writer.Start();
-
}
-
-
private void ReceiveRequested()
-
{
-
_myRoom = _groups.MyRoom(Request.QueryString["group"]);
-
-
Read();
-
Response.Write(_myRoom.AllConversation);
-
}
-
-
public void Read()
-
{
-
Monitor.Enter(_myRoom);
-
Monitor.Wait(_myRoom);
-
Monitor.Exit(_myRoom);
-
}
-
-
public void Write()
-
{
-
Monitor.Enter(_myRoom);
-
-
/// rarely happend when more than one request to write arrive to
-
/// server at the same time.
-
if (_myRoom._writer)
-
Monitor.Wait(_myRoom);
-
-
_myRoom._writer = true;
-
-
_myRoom._allText += _myRoom.NewMessageContent;
-
-
_myRoom._writer = false;
-
Monitor.PulseAll(_myRoom);
-
Monitor.Exit(_myRoom);
-
try { Thread.CurrentThread.Abort(); }
-
catch { }
-
}
-
}
Readers only wait until a writer pulse all of them.
3) Group class : is shared among all classes that reference it (singleton)
- public class Groups
-
{
-
static readonly Groups _groups = new Groups();
-
List<ChatRoom> _rooms = new List<ChatRoom>();
-
bool editor;
-
-
private Groups()
-
{
-
-
}
-
-
public ChatRoom EnterChat(string roomName, string userName)
-
{
-
Monitor.Enter(this);
-
-
if (editor)
-
Monitor.Wait(this);
-
editor = true;
-
-
foreach (ChatRoom room in _rooms)
-
{
-
if (room.Name == roomName)
-
{
-
editor = false;
-
Monitor.PulseAll(this);
-
Monitor.Exit(this);
-
return room;
-
}
-
}
-
-
ChatRoom newRoom = new ChatRoom(roomName);
-
_rooms.Add(newRoom);
-
-
editor = false;
-
Monitor.PulseAll(this);
-
Monitor.Exit(this);
-
return newRoom;
-
}
-
-
public ChatRoom MyRoom(string roomName)
-
{
-
foreach (ChatRoom room in _rooms)
-
if (room.Name == roomName)
-
return room;
-
return null;
-
}
-
-
public static Groups Instance
-
{
-
get { return _groups; }
-
}
-
}
4) ChattRoom class : contains only string to save the conversation.
- public class ChatRoom
-
{
-
readonly string _name;
-
-
public string _allText = string.Empty;
-
public string _newMessage;
-
-
public bool _writer;
-
-
public ChatRoom(string name)
-
{
-
_name = name;
-
}
-
-
public string NewMessageContent
-
{
-
set { _newMessage = value; }
-
get { return _newMessage; }
-
}
-
-
public string Name
-
{
-
get { return _name; }
-
}
-
-
public string AllConversation
-
{
-
get { return _allText; }
-
}
-
}
Everything works fine but when a writer PulseAll waiting threads (Readers) only one thread notified and response.
Please any help! Any idea!
Thanks in advanced.