I'm doing a class for working with the serial port.
It's all going quiet until the item to receive a data through the serial port, the class raise an event in the main application.
My question is: how to pass parameters to a delegate and use it in my class because my class is so independent.
Below the sources and where I like to spend delegates.
Class control serial port:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace TCCExterna.Lib
{
public class PortaSerial //: IDisposable
{
private SerialPort serialPort;
private Queue<byte> recievedData = new Queue<byte>();
public PortaSerial()
{
serialPort = new SerialPort();
serialPort.DataReceived += serialPort_DataReceived;
}
public void Abrir(string porta, int velocidade)
{
serialPort.PortName = porta;
serialPort.BaudRate = velocidade;
serialPort.Open();
}
public string[] GetPortas()
{
return SerialPort.GetPortNames();
}
public string[] GetVelocidades()
{
return new string[] { "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200" };
}
void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
data.ToList().ForEach(b => recievedData.Enqueue(b));
processData();
// like this use LineReceivedEvent or LineReceived
}
private void processData()
{
// Determine if we have a "packet" in the queue
if (recievedData.Count > 50)
{
var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
}
}
public void Dispose()
{
if (serialPort != null)
serialPort.Dispose();
}
}
}
Program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using TCCExterna.Lib;
namespace TCCExterna
{
public partial class FormPrincipal : Form
{
PortaSerial sp1 = new PortaSerial(); // like this command passed LineReceivedEvent or LineReceived
public delegate void LineReceivedEvent(string line);
public void LineReceived(string line)
{
//What to do with the received line here
}
public FormPrincipal()
{
InitializeComponent();
cmbPortas.Items.AddRange(sp1.GetPortas());
cmbVelocidade.Items.AddRange(sp1.GetVelocidades());
}
}
}
If I got it clearly, what you want is this: (se quiser pode explicar melhor em português, depois a gente traduz pro site).
//delcare an event args clas
public class LineReceivedEventArgs : EventArgs
{
//Data to pass to the event
public string LineData{get; private set;}
public LineReceivedEventArgs(string lineData)
{
this.LineData = lineData
}
}
//declare a delegate
public delegate void LineReceivedEventHandler(object sender, LineReceivedEventArgs Args);
public class PortaSerial //: IDisposable
{
private SerialPort serialPort;
private Queue<byte> recievedData = new Queue<byte>();
//add event to class
public event LineReceivedEventHandler LineReceived;
public PortaSerial()
{
serialPort = new SerialPort();
serialPort.DataReceived += serialPort_DataReceived;
}
public void Abrir(string porta, int velocidade)
{
serialPort.PortName = porta;
serialPort.BaudRate = velocidade;
serialPort.Open();
}
public string[] GetPortas()
{
return SerialPort.GetPortNames();
}
public string[] GetVelocidades()
{
return new string[] { "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200" };
}
void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
data.ToList().ForEach(b => recievedData.Enqueue(b));
processData();
//raise event here
if (this.LineReceived != null)
LineReceived(this, new LineReceivedEventArgs("some line data"));
}
private void processData()
{
// Determine if we have a "packet" in the queue
if (recievedData.Count > 50)
{
var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
}
}
public void Dispose()
{
if (serialPort != null)
serialPort.Dispose();
}
}
public partial class FormPrincipal : Form
{
PortaSerial sp1 = new PortaSerial(); // like this command passed LineReceivedEvent or LineReceived
// event handler method
void sp1_LineReceived(object sender, LineReceivedEventArgs Args)
{
//do things with line
MessageBox.ShowDialog(Args.LineData);
}
public FormPrincipal()
{
InitializeComponent();
//add handler to event
sp1.LineReceived += new LineReceivedEventHandler(sp1_LineReceived);
cmbPortas.Items.AddRange(sp1.GetPortas());
cmbVelocidade.Items.AddRange(sp1.GetVelocidades());
}
}
Related
I open multiple serial ports and assign the DataReceived event to a single method. If now multiple com ports receive at the same time something, SerialPort_DataReceived is called parallel(?) so i tried to use lock so that only one event could be handled at the same time.
using System;
using System.Collections.Generic;
using System.Windows;
using System.IO.Ports;
using System.Text;
namespace MainApplication
{
public partial class MainWindow : Window
{
private SerialConnectionHandler m_SerialConnectionHandler;
public MainWindow()
{
InitializeComponent();
m_SerialConnectionHandler = new SerialConnectionHandler();
m_SerialConnectionHandler.ResponseReceived += SerialConnectionHandler_ResponseReceived;
}
private void SerialConnectionHandler_ResponseReceived(object sender, EventArgs e)
{
// Do something.
}
}
public class SerialConnectionHandler
{
private List<SerialPort> m_SerialConnections;
private List<SerialCommand> m_CommandQueue;
private object m_DataReceivedLock;
public event EventHandler ResponseReceived;
public SerialConnectionHandler()
{
m_SerialConnections = new List<SerialPort>();
m_CommandQueue = new List<SerialCommand>();
m_DataReceivedLock = new object();
foreach (var comPortName in SerialPort.GetPortNames())
{
var newSerialPort = new SerialPort(comPortName);
newSerialPort.DataReceived += SerialPort_DataReceived;
var newSerialCommand = new SerialCommand(comPortName, "Command", "Response");
newSerialPort.Open();
newSerialPort.Write(newSerialCommand.Command, 0, newSerialCommand.Command.Length);
m_SerialConnections.Add(newSerialPort);
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock (m_DataReceivedLock)
{
var serialPort = (SerialPort)sender;
var receivedContent = new byte[serialPort.BytesToRead];
serialPort.Read(receivedContent, 0, receivedContent.Length);
// Clear in buffer.
serialPort.DiscardInBuffer();
// Do something which could lead to problems if multiple com ports receive at the same time something.
foreach (var command in m_CommandQueue.FindAll(command => command.SerialPortName.Equals(serialPort.PortName)))
{
if (command.ExpectedResponse.Equals(receivedContent.ToString()))
{
ResponseReceived?.Invoke(this, new EventArgs());
m_CommandQueue.Remove(command);
break;
}
}
}
}
}
public class SerialCommand
{
public string SerialPortName { get; }
public byte[] Command { get; }
public string ExpectedResponse { get; }
public SerialCommand(string serialPortName, string command, string expectedResponse)
{
SerialPortName = serialPortName;
Command = Encoding.ASCII.GetBytes(command);
ExpectedResponse = expectedResponse;
}
}
}
My question is now, could lock lead to missed received content due to the fact that not every event is handled immediately? I'm calling SerialPort.Read() and SerialPort.DiscardInBuffer() from inside the lock block.
I try to use code from How to use C# BackgroundWorker to report progress in native C++ code? for change progressBar in WinForms.
But the function which is called from c++ dll does not started (CSharpReportProgressStatus()), if I create a form. Without creation of the form it works fine.
CppLayer.h:
#define DLLAPI __declspec(dllexport)
extern "C"
{
typedef void (__stdcall *ReportProgressCallback)(int, char *);
typedef bool (__stdcall *CancellationPendingCallback)();
struct DLLAPI WorkProgressInteropNegotiator
{
ReportProgressCallback progressCallback;
CancellationPendingCallback cancellationPending;
bool cancel;
};
DLLAPI void __stdcall CppLongFunction(WorkProgressInteropNegotiator& negotiator);
}
CppLayer.cpp:
#include "CppLayer.h"
#include <iostream>
#include <windows.h> //Для sleep
typedef void (__stdcall * pfnCallback)(int progress, int* cancel);
extern "C"
{
DLLAPI void __stdcall CppLongFunction(WorkProgressInteropNegotiator& negotiator)
{
const int STEP_COUNT = 12;
char * messages[3] = {"ONE", "TWO", "THREE"};
for (int i = 0; i < STEP_COUNT; i++)
{
Sleep(100);
if (negotiator.cancellationPending()) {
negotiator.cancel = true;
break;
}
std::cout << "Calculate " << i << std::endl;
negotiator.progressCallback((i + 1) * 100 / STEP_COUNT, messages[i % 3]);
}
}
};
Program.cs:
using System;
using System.Windows.Forms;
namespace CallBackFromCpp
{
static class Program
{
[STAThread]
public static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Presenter p = new Presenter();
Application.Run(p.Init());
}
}
}
Form1.cs:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace CallBackFromCpp
{
public partial class Form1 : Form
{
public event EventHandler StartEvent;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (StartEvent != null)
StartEvent(this, e);
}
}
}
Presenter.cs:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace CallBackFromCpp
{
public class Presenter
{
Form1 _view;
public ApplicationContext Init()
{
_view = new Form1();
_view.StartEvent += _view_StartEvent;
return new ApplicationContext(_view);
}
public delegate void ReportProgressCallback(int percentage, string message);
public delegate bool CancellationPendingCallback();
[StructLayout(LayoutKind.Sequential)]
public class WorkProgressInteropNegotiator
{
public ReportProgressCallback reportProgress;
public CancellationPendingCallback cancellationPending;
#pragma warning disable 0649
// C# does not see this member is set up in native code, we disable warning to avoid it.
public bool cancel;
#pragma warning restore 0649
}
[DllImport("CppLayer.dll")]
public static extern void CppLongFunction([In, Out] WorkProgressInteropNegotiator negotiator);
static EventWaitHandle resetEvent = null;
void _view_StartEvent(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.ProgressChanged += CSharpReportProgressStatus;
bw.DoWork += CSharpLongFunctionWrapper;
bw.RunWorkerCompleted += CSharpReportComplete;
resetEvent = new AutoResetEvent(false);
bw.RunWorkerAsync();
resetEvent.WaitOne();
}
void CSharpLongFunctionWrapper(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
WorkProgressInteropNegotiator negotiator = new WorkProgressInteropNegotiator();
negotiator.reportProgress = new ReportProgressCallback(bw.ReportProgress);
negotiator.cancellationPending = new CancellationPendingCallback(() => bw.CancellationPending);
GCHandle gch = GCHandle.Alloc(negotiator);
CppLongFunction(negotiator);
gch.Free();
e.Cancel = negotiator.cancel;
}
void CSharpReportProgressStatus(object sender, ProgressChangedEventArgs e)
{
string message = e.UserState as string;
_view.richTextBox1.Text += String.Format("Report {0:00}% with message '{1}'", e.ProgressPercentage, message);
_view.progressBar1.PerformStep();
BackgroundWorker bw = sender as BackgroundWorker;
if (e.ProgressPercentage > 50)
bw.CancelAsync();
}
void CSharpReportComplete(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
_view.richTextBox1.Text = "Long operation canceled!";
}
else if (e.Error != null)
{
_view.richTextBox1.Text = String.Format("Long operation error: {0}", e.Error.Message);
}
else
{
_view.richTextBox1.Text += "Long operation complete!";
}
resetEvent.Set();
}
}
}
The problem was solved transfer dll call in a separate thread and GUI update via invoke from this thread.
Form1.cs:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace CallBackFromCpp
{
public partial class Form1 : Form
{
public event EventHandler StartEvent;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (StartEvent != null)
StartEvent(this, e);
}
private void button2_Click(object sender, EventArgs e)
{
if (StopEvent != null)
StopEvent(this, e);
}
}
}
Presenter.cs:
using System;
using System.Threading;
using System.Windows.Forms;
namespace CallBackFromCpp
{
public class Presenter
{
Form1 _view;
WorkerClass _wc;
public ApplicationContext Init()
{
_view = new Form1();
_view.StartEvent += _view_StartEvent;
_view.StopEvent += _view_StopEvent;
return new ApplicationContext(_view);
}
void _view_StopEvent(object sender, EventArgs e)
{
if (_wc != null)
_wc.Stop = true;
}
delegate void ShowProgressDelegate(int progressPercentage, string message);
private void ShowProgress(int progressPercentage, string message)
{
_view.richTextBox1.Text += String.Format("Report {0:00}% with message '{1}'\n", progressPercentage, message);
_view.progressBar1.PerformStep();
}
void _view_StartEvent(object sender, EventArgs e)
{
ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress);
_wc = new WorkerClass(_view, showProgress);
Thread t = new Thread(new ThreadStart(_wc.RunProcess));
t.IsBackground = true; //make them a daemon - prevent thread callback issues
t.Start();
}
}
}
WorkerClass.cs:
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace CallBackFromCpp
{
public class WorkerClass
{
/// <summary>
/// Usually a form or a winform control that implements "Invoke/BeginInvode"
/// </summary>
ContainerControl _sender = null;
/// <summary>
/// The delegate method (callback) on the sender to call
/// </summary>
Delegate _senderDelegate = null;
public delegate void ReportProgressCallback(int percentage, string message);
public delegate bool CancellationPendingCallback();
[StructLayout(LayoutKind.Sequential)]
public class WorkProgressInteropNegotiator
{
public ReportProgressCallback reportProgress;
public CancellationPendingCallback cancellationPending;
#pragma warning disable 0649
// C# does not see this member is set up in native code, we disable warning to avoid it.
public bool cancel;
#pragma warning restore 0649
}
[DllImport("CppLayer.dll")]
public static extern void CppLongFunction([In, Out] WorkProgressInteropNegotiator negotiator);
/// <summary>
/// Constructor called by calle using ThreadPool OR ThreadStart
/// </summary>
public WorkerClass(ContainerControl sender, Delegate senderDelegate)
{
_sender = sender;
_senderDelegate = senderDelegate;
}
/// <summary>
/// Method for ThreadStart delegate
/// </summary>
public void RunProcess()
{
Thread.CurrentThread.IsBackground = true; //make them a daemon
WorkProgressInteropNegotiator negotiator = new WorkProgressInteropNegotiator();
negotiator.reportProgress = new ReportProgressCallback(ReportProgress);
negotiator.cancellationPending = new CancellationPendingCallback(() => { return Stop; });
// Refer for details to
// "How to: Marshal Callbacks and Delegates Using C++ Interop"
// http://msdn.microsoft.com/en-us/library/367eeye0%28v=vs.100%29.aspx
GCHandle gch = GCHandle.Alloc(negotiator);
CppLongFunction(negotiator);
gch.Free();
}
private void ReportProgress(int progressPercentage, string message)
{
_sender.BeginInvoke(_senderDelegate, new object[] { progressPercentage, message });
}
volatile bool _stop = false;
public bool Stop
{
set
{
_stop = value;
}
get
{
return _stop;
}
}
}
}
I am trying to do serial communication with Arduino to control LED by Unity in C#.
These below are my codes copied from a sample link:
SerialHandler.cs
using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;
public class SerialHandler : MonoBehaviour
{
public delegate void SerialDataReceivedEventHandler(string message);
public event SerialDataReceivedEventHandler OnDataReceived;
public string portName = "/dev/tty.usbmodem1421";
public int baudRate = 9600;
private SerialPort serialPort_;
private Thread thread_;
private bool isRunning_ = false;
private string message_;
private bool isNewMessageReceived_ = false;
void Awake()
{
Open();
}
void Update()
{
if (isNewMessageReceived_) {
OnDataReceived(message_);
}
}
void OnDestroy()
{
Close();
}
private void Open()
{
serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
serialPort_.Open();
isRunning_ = true;
thread_ = new Thread(Read);
thread_.Start();
}
private void Close()
{
isRunning_ = false;
if (thread_ != null && thread_.IsAlive) {
thread_.Join();
}
if (serialPort_ != null && serialPort_.IsOpen) {
serialPort_.Close();
serialPort_.Dispose();
}
}
private void Read()
{
while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) {
try {
if (serialPort_.BytesToRead > 0) {
message_ = serialPort_.ReadLine();
isNewMessageReceived_ = true;
}
} catch (System.Exception e) {
Debug.LogWarning(e.Message);
}
}
}
public void Write(string message)
{
try {
serialPort_.Write(message);
} catch (System.Exception e) {
Debug.LogWarning(e.Message);
}
}
}
LedController.cs
using UnityEngine;
using System.Collections;
public class LedController : MonoBehaviour
{
public SerialHandler serialHandler;
void Update()
{
if ( Input.GetKeyDown(KeyCode.A) ) {
serialHandler.Write("0");
}
if ( Input.GetKeyDown(KeyCode.S) ) {
serialHandler.Write("1");
}
}
}
However, when pressing the keyboard A and S to switch a LED on/off, it doesn't work.
There is error message as I get.
Object reference not set to an instance of an object
That would be really awesome if wisdoms help me out!
Thanks,
m
I'm writing a small WPF application in C# using Kinect and COMs to communicate to an arduino.
I have a combobox where the user can choose the port that he wants to use, I have a watcher on my COMs and everytime a device is Plugged/Unplugged I want to refresh my combobox.
My problem is that the calling to the function is in another class so I have a thread error
Here is the portion of code that doesn't work :
namespace Microsoft.Samples.Kinect.SkeletonBasics
{
using System.IO;
using System.IO.Ports;
using System;
using System.Management;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using System.Windows.Controls;
using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit;
public partial class MainWindow : Window
{
private WMIReceiveEvent receiveEvent = new WMIReceiveEvent();
internal static ComboBox comboBox; //Internal static variable so it can be used in static method
public MainWindow()
{
InitializeComponent();
}
private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
using (receiveEvent) {}
}
private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
comboBox = Com_ComboBox;
string[] ports = SerialPort.GetPortNames();
if (ports.Length == 0)
{
Default_Text.Content = "Aucun port détecté";
comboBox.IsHitTestVisible = false;
comboBox.Focusable = false;
}
else Default_Text.Content = "Arduino sur le port :";
comboBox.SelectedIndex = 0;
foreach (string port in ports)
{
comboBox.Items.Add(port);
}
}
internal static void Refresh_Coms() //I'm trying to call this function from the other class but I get a thread error
{
comboBox.Items.Clear();
ComboBoxItem Default_Text = (ComboBoxItem) comboBox.ItemContainerGenerator.ContainerFromIndex(0);
string[] ports = SerialPort.GetPortNames();
if (ports.Length == 0)
{
Default_Text.Content = "Aucun port détecté";
comboBox.IsHitTestVisible = false;
comboBox.Focusable = false;
comboBox.SelectedIndex = 0;
}
else Default_Text.Content = "Arduino sur le port :";
foreach (string port in ports)
{
comboBox.Items.Add(port);
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
public class WMIReceiveEvent : IDisposable
{
private ManagementEventWatcher watcherAttach;
private ManagementEventWatcher watcherDetach;
public WMIReceiveEvent()
{
try
{
watcherAttach = new ManagementEventWatcher();
watcherAttach.EventArrived += Attaching;
watcherAttach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
watcherAttach.Start();
watcherDetach = new ManagementEventWatcher();
watcherDetach.EventArrived += Detaching;
watcherDetach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
watcherDetach.Start();
return;
}
catch (ManagementException err)
{
MessageBox.Show("An error occurred while trying to receive an event: " + err.Message);
}
}
public void Dispose()
{
try
{
watcherAttach.Stop();
watcherDetach.Stop();
watcherAttach.Dispose();
watcherDetach.Dispose();
}
catch
{
MessageBox.Show("An error occurred while trying to close COM event Handler");
}
}
void Attaching(object sender, EventArrivedEventArgs e)
{
if (sender != watcherAttach) return;
Console.WriteLine("Attaching");
MainWindow.Refresh_Coms(); //I can call the function but the thread can't modify the ComboBox
}
void Detaching(object sender, EventArrivedEventArgs e)
{
if (sender != watcherDetach) return;
Console.WriteLine("Detaching");
MainWindow.Refresh_Coms();
}
~WMIReceiveEvent()
{
this.Dispose();
}
}
}
I'm a little new to C#, I've searched on the web but I can't find an easy solution for doing that, can somebody help me please ?
Add SynchronizationContext to Your WMIReceiveEvent class, like:
public class WMIReceiveEvent : IDisposable
{
private readonly SynchronizationContext _syncContext;
public WMIReceiveEvent(SynchronizationContext syncContext)
{
_cyncContext = syncContext;
}
}
and wrap of calling MainWindow.Refresh_Coms(); with Send method of SynchronizationContext:
_syncContext.Send(o => MainWindow.Refresh_Coms(), null);
And last thing is creating Your WMIReceiveEvent class:
private WMIReceiveEvent receiveEvent = new WMIReceiveEvent(SynchronizationContext.Current);
More about SynchronizationContext.
I am trying to get my Chat system to work. I have a Client/Server launch per an app. I have Client1 talking to Server 2 and Client2 to Server1 but I cannot figure out how to print the information being sent to the servers to the chat windows of their corresponding Clients.
ChatRoom
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace ChatRoom
{
public class Class1:MarshalByRefObject
{
// initialize Arraylist to store users signed into chat room
private static ArrayList userNames = new ArrayList();
private static string chatWindow; // fuck u, now ye be a static var
public void sendMessage(string message)
{
Console.WriteLine(message);
//if (message != null)
// {
//add to chat window
chatWindow += message + Environment.NewLine;
//}
}
//public void test()
//{
// Console.WriteLine("pizza");
//}
public void addUserName(string UserName)
{
String test = UserName;
Console.WriteLine(test);
userNames.Add(test);
Console.WriteLine("0");
}
public void deleteUserName(string userName)
{
if (userName != null)
{
userNames.Remove(userName);
}
}
public ArrayList userList()
{
return userNames; // userNames
}
public string OutputWindow()
{
return chatWindow;
}
}
}
SERVER
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using ChatRoom;
using System.Runtime.Remoting.Channels.Http;
using RemoteServer;
namespace RemoteServer
{
public partial class Form1 : Form
{
private int channelNum;
private static string temp;
public Form1()
{
InitializeComponent();
}
private void buttonConfirm_Click(object sender, EventArgs e)
{
temp = textBoxPort.Text;
channelNum = Convert.ToInt32(temp);
HttpChannel ServerChannel = new HttpChannel(channelNum);
Console.WriteLine("httpChannel Set");
this.Close(); // close GUI
ChannelServices.RegisterChannel(ServerChannel, false);
Console.WriteLine("channel registered");
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Class1), "ChatRoom",
WellKnownObjectMode.SingleCall);
Console.WriteLine("working");
Console.WriteLine("Port number is " + channelNum);
Console.ReadKey();
}
}
}
CLIENT
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ChatRoom;
using RemoteServer;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Threading;
using System.Diagnostics;
using System.Timers;
namespace ClientServerGui
{
public partial class Form1 : Form
{
private Class1 server;
private Thread thread;
//private Thread thread2;
//private HttpChannel ClientHttpChannel;
private string UserName;
public Form1()
{
InitializeComponent();
}
public static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
private void logoutToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void ConfigureServer(string port)
{
HttpClientChannel ClientChannel = new HttpClientChannel();
ChannelServices.RegisterChannel(ClientChannel, false);
RemotingConfiguration.RegisterWellKnownClientType(typeof(Class1), "http://localhost:"
+ textBoxPort.Text + "/ChatRoom");
}
private void buttonSend_Click(object sender, EventArgs e)
{
//ArrayList displayUsers = server.userList();
//string send = textBoxSend.Text;
//textBoxChatWindowDisplay.Text += send;
//combine User's name with input text
string send = UserName + ": " + textBoxSend.Text;
while( textBoxSend.Text != "")
{
//send message
server.sendMessage(send);
//Clear and focus to start new message
textBoxSend.Clear();
buttonSend.Focus();
}
textBoxChatWindowDisplay.Text += send;
textBoxChatWindowDisplay.Text = server.OutputWindow();
//textBoxChatWindowDisplay.Text += "\n";
//listBoxUserList.Items.Clear();
// foreach (string x in displayUsers)
// {
// listBoxUserList.Items.Add(displayUsers);
// }
}
public void chatReloadTimer_Tick(object sender, EventArgs e)
{
textBoxChatWindowDisplay.Text = server.OutputWindow();
StartServer();
}
private void buttonConnect_Click(object sender, EventArgs e)
{
//RemoteServer.Form1 port = new RemoteServer.Form1();
//string Serverport = port.ServerPort();
if (textBoxUserName.Text != "")
{
UserName = textBoxUserName.Text;
//ClientHttpChannel = new HttpChannel();
//ChannelServices.RegisterChannel(ClientHttpChannel, false);
if (textBoxPort.Text == "")
{
textBoxPort.Text = "9000";
}
//server1
ConfigureServer(textBoxPort.Text);
//server2
// ConfigureServer(Serverport);
server = new Class1();
//add user
server.addUserName(UserName);
//server.test();
//new thread
thread = new Thread(new ThreadStart(StartServer));
//start thread
thread.Start();
//new thread
//thread2 = new Thread(new ThreadStart(StartServer2));
//start thread
//thread2.Start();
buttonSend.Focus();
System.Windows.Forms.Timer chatReloadTimer = new System.Windows.Forms.Timer();
chatReloadTimer.Interval = (100); // .1 seconds refresh
chatReloadTimer.Tick += new EventHandler(chatReloadTimer_Tick);
chatReloadTimer.Start();
}
}
private void StartServer()
{
string currentChatWindow;
//set array list to capture people joining server
ArrayList usersArrayList = server.userList();
//** BAD FOR CHATROOM STYLE****
//if (listBoxUserList.ItemHeight > 0)//if not enmpy kill all
//{
// //empty listbox
this.Invoke(new MethodInvoker(delegate() { listBoxUserList.Items.Clear(); }));
//}
// Add all users to listbox
//while (usersAL != null)
//{
foreach (string x in usersArrayList)
{
//listBoxUserList.Items.Add(UserName);
this.Invoke(new MethodInvoker(delegate() { listBoxUserList.Items.Add(x); }));
}
//}
//display data to user
currentChatWindow = server.OutputWindow();
//textBoxChatWindowDisplay.Text = currentChatWindow;
this.Invoke(new MethodInvoker(delegate() { textBoxChatWindowDisplay.Text = currentChatWindow; }));
//listBoxUserList.Items.Add(
}
private void Form1_Load(object sender, EventArgs e)
{
//Boolean on = true;
Process start = new Process();
start.StartInfo.FileName = "RemoteServer";
start.Start();
MessageBox.Show("Continue?", "Continue", MessageBoxButtons.OKCancel);
//while (on == true)
//{
// Thread.Sleep(1);
// textBoxChatWindowDisplay.Text = server.OutputWindow();
//}
buttonSend.Focus();
}
}
}