Remoting using a specific object - c#

I've been playing with XNA and want to try and make a game work over LAN but it turns out that to do this I need to use something called remoting. Anyway I managed to get this to work
public class TestObject : MarshalByRefObject
{
int testInt;
public Level()
{
this.testInt = 5.Zero;
}
public int GetNumber()
{
return testInt;
}
}
and my server
channel = new TcpChannel(4444);
ChannelServices.RegisterChannel(channel, false);
Type type = Type.GetType("Domain.Level,Domain");
RemotingConfiguration.RegisterWellKnownServiceType(type,
"FirstRemote",
WellKnownObjectMode.Singleton);
and client
this.chanel = new TcpChannel();
ChannelServices.RegisterChannel(chanel, false);
this.testObject = (TestObject)Activator.GetObject(typeof(TestObject),
"tcp://localhost:4444/FirstRemote");
so that works but the problem is that the server has no way to access the object and I cant make a constructor that takes arguments so there is no way to initialize any data on the test object. How do I make an object, and then make it use that instead of making a new object?

Unfortunately, you'll probably find that realtime network communication in games is more complex than the current direction you're taking. Most games use persistent socket connections to pass information back and forth between clients and other methods are generally too slow for realtime networking.
I recommend looking into the Lidgren networking library. Lidgren abstracts network communication and makes it much easier to serialize data into very small and fast packets that can be transferred via several reliability modes across UDP and TCP. You can find the Lidgren project here:
http://code.google.com/p/lidgren-network-gen3/
As a side note, it was very valuable for me to read how the Unreal Engine does networking here:
http://udn.epicgames.com/Three/NetworkingOverview.html
And I wrote a blog that demonstrates some specific details about implementing a client/server pattern:
http://syndicatex.com/flatredball/flatredball-and-lidgren-multiplayer-networking/

Related

Callback from native Java to Unity's C# script has some weird (latency?) issue

I'm developing a Unity plugin that uses BLE to communicate with some device. I have implementation for both Windows (using P/Invoke to this device's SDK) and Android, which uses Unity's helper classes for interfacing with the JVM. The device's SDK in Java has a callback for incoming new data, the callback looks like this:
#Override
public void onDeviceData(BluetoothDevice device, byte[] data) {
}
I've implemented a class that inherits Unity's AndroidJavaProxy to register a callback handler from the C# side:
class Callbacks : AndroidJavaProxy
{
ConcurrentQueue<byte[]> IncomingMessages { get; private set; }
public Callbacks()
: base("com.example.sdk.SdkCallbacks")
{
IncomingMessages = new ConcurrentQueue<byte[]>();
}
void onDeviceData(AndroidJavaObject device, byte[] data)
{
IncomingMessages.Enqueue(data);
}
}
I have a script in the scene that deques this data in the Update() function like so:
while (!_device.IncomingMessages.IsEmpty)
{
byte[] data;
if (_device.IncomingMessages.TryDequeue(out data))
{
// do something with the data
}
}
In my specific case I'm using the data coming from the device to move a point on the screen (think "wireless mouse").
That works pretty well, until I need to get high-rate data from the device (About ~60 callbacks per second with the data parameter containing an array of ~30 bytes). At first everything looks okay, but after a few seconds the point starts to lag heavily behind the actual input from the device, and the lag only gets bigger with time.
I've tried checking if the IncomingMessages queue is getting too big which would mean the producer outpace the consumer by a lot, causing an ever-increasing delay, but that was not the case, IncomingMessages.Count always shows 0-2.
This does not happen when running the code on Windows and using the device's SDK from a regular Android app also works well.
Can this be a marshaling overhead between the JNI and the CLR runtimes? Or something similar?
If so, is there anything I can do about it? I know Unity has another way of communicating between native and the scripting runtime with UnitySendMessage but I'm not sure if that won't have the same problem.

Process launcher launching process inside of a windows service but the application window is not opening [duplicate]

I currently have a single application that needs to be started from a windows service that i am coding in .net 3.5. This application is currently running as the user who ran the service, in my case the SYSTEM user. If running as the SYSTEM user it does not show the application to the users desktop. Thoughts? advice?
//constructor
private Process ETCHNotify = new Process();
//StartService()
ETCHNotify.StartInfo.FileName = baseDir + "\\EtchNotify.exe";
ETCHNotify.StartInfo.UseShellExecute = false;
//BackgroundWorkerThread_DoWork()
if (!systemData.GetUserName().Equals(""))
{
// start ETCHNotify
try {
ETCHNotify.Start();
}
catch (Exception ex)
{
systemData.Run("ERR: Notify can't start: " + ex.Message);
}
}
I only execute the try/catch if the function i have written GetUserName() (which determines the username of the user running explorer.exe) is not null
again to reiterate: desired functionality is that this starts ETCHNotify in a state that allows it to interact with the currently logged in user as determined by GetUserName()
Collage of some post found around (this and this)
Note that as of Windows Vista, services are strictly forbidden from interacting directly with a user:
Important: Services cannot directly interact with a user as of Windows
Vista. Therefore, the techniques mentioned in the section titled Using
an Interactive Service should not be used in new code.
This "feature" is broken, and conventional wisdom dictates that you shouldn't have been relying on it anyway. Services are not meant to provide a UI or allow any type of direct user interaction. Microsoft has been cautioning that this feature be avoided since the early days of Windows NT because of the possible security risks.
There are some possible workarounds, however, if you absolutely must have this functionality. But I strongly urge you to consider its necessity carefully and explore alternative designs for your service.
Use WTSEnumerateSessions to find the right desktop, then CreateProcessAsUser to start the application on that desktop (you pass it the handle of the desktop as part of the STARTUPINFO structure) is correct.
However, I would strongly recommend against doing this. In some environments, such as Terminal Server hosts with many active users, determining which desktop is the 'active' one isn't easy, and may not even be possible.
A more conventional approach would be to put a shortcut to a small client app for your service in the global startup group. This app will then launch along with every user session, and can be used start other apps (if so desired) without any juggling of user credentials, sessions and/or desktops.
Ultimately in order to solve this i took the advice of #marco and the posts he mentioned. I have created the service to be entirely independent of the tray application that interacts with the user. I did however install the Tray application via registry 'start up' methods with the service. The Service installer will now install the application which interacts with the user as well... This was the safest and most complete method.
thanks for your help everyone.
I wasn't going to answer this since you already answered it, (and it's oh, what? going on 2.5 years OLD now!?) But there are ALWAYS those people who are searching for this same topic, and reading the answers...
In order to get my service to Interact with the Desktop, no matter WHAT desktop, nor, how MANY desktops, nor if the service was even running on the SAME COMPUTER as the desktop app!! None of that matters with what I got here... I won't bore you with the details, I'll just give you the meat and potatoes, and you and let me know if you want to see more...
Ok. First thing I did was create an Advertisement Service. This is a thread that the service runs, opens up a UDP socket to listen for broadcasts on the network. Then, using the same piece of code, I shared it with the client app, but it calls up Advertise.CLIENT, rather than Advertise.SERVER... The CLIENT opens the port I expect the service to be on, and broadcasts a message, "Hello... Is there anybody out there??", asking if they're there ANY servers listening, and if so, reply back to THIS IP address with your computer name, IP Address and port # where I can find the .NET remoting Services..." Then it waits a small amount of time-out time, gathers up the responses it gets, and if it's more than one, it presents the user with a dialog box and a list of services that responded... The Client then selects one, or, if only ONE responded, it will call Connect((TServerResponse) res); on that, to get connected up. At this point, the server is using Remoting Services with the WellKnownClientType, and WellKnownServerType to put itself out there...
I don't think you are too interested in my "Auto-Service locater", because a lot of people frown on UDP, even more so when your app start broadcasting on large networks. So, I'm assuming you'd be more interested in my RemotingHelper, that gets the client connected up to the server. It looks like this:
public static Object GetObject(Type type)
{
try {
if(_wellKnownTypes == null) {
InitTypeCache();
}
WellKnownClientTypeEntry entr = (WellKnownClientTypeEntry)_wellKnownTypes[type];
if(entr == null) {
throw new RemotingException("Type not found!");
}
return System.Activator.GetObject(entr.ObjectType, entr.ObjectUrl);
} catch(System.Net.Sockets.SocketException sex) {
DebugHelper.Debug.OutputDebugString("SocketException occured in RemotingHelper::GetObject(). Error: {0}.", sex.Message);
Disconnect();
if(Connect()) {
return GetObject(type);
}
}
return null;
}
private static void InitTypeCache()
{
if(m_AdvertiseServer == null) {
throw new RemotingException("AdvertisementServer cannot be null when connecting to a server.");
}
_wellKnownTypes = new Dictionary<Type, WellKnownClientTypeEntry>();
Dictionary<string, object> channelProperties = new Dictionary<string, object>();
channelProperties["port"] = 0;
channelProperties["name"] = m_AdvertiseServer.ChannelName;
Dictionary<string, object> binFormatterProperties = new Dictionary<string, object>();
binFormatterProperties["typeFilterLevel"] = "Full";
if(Environment.UserInteractive) {
BinaryServerFormatterSinkProvider binFormatterProvider = new BinaryServerFormatterSinkProvider(binFormatterProperties, null);
_serverChannel = new TcpServerChannel(channelProperties, binFormatterProvider);
// LEF: Only if we are coming form OUTSIDE the SERVICE do we want to register the channel, since the SERVICE already has this
// channel registered in this AppDomain.
ChannelServices.RegisterChannel(_serverChannel, false);
}
System.Diagnostics.Debug.Write(string.Format("Registering: {0}...\n", typeof(IPawnStatServiceStatus)));
RegisterType(typeof(IPawnStatServiceStatus),m_AdvertiseServer.RunningStatusURL.ToString());
System.Diagnostics.Debug.Write(string.Format("Registering: {0}...\n", typeof(IPawnStatService)));
RegisterType(typeof(IPawnStatService), m_AdvertiseServer.RunningServerURL.ToString());
System.Diagnostics.Debug.Write(string.Format("Registering: {0}...\n", typeof(IServiceConfiguration)));
RegisterType(typeof(IServiceConfiguration), m_AdvertiseServer.RunningConfigURL.ToString());
}
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration, RemotingConfiguration=true)]
public static void RegisterType(Type type, string serviceUrl)
{
WellKnownClientTypeEntry clientType = new WellKnownClientTypeEntry(type, serviceUrl);
if(clientType != RemotingConfiguration.IsWellKnownClientType(type)) {
RemotingConfiguration.RegisterWellKnownClientType(clientType);
}
_wellKnownTypes[type] = clientType;
}
public static bool Connect()
{
// Init the Advertisement Service, and Locate any listening services out there...
m_AdvertiseServer.InitClient();
if(m_AdvertiseServer.LocateServices(iTimeout)) {
if(!Connected) {
bConnected = true;
}
} else {
bConnected = false;
}
return Connected;
}
public static void Disconnect()
{
if(_wellKnownTypes != null) {
_wellKnownTypes.Clear();
}
_wellKnownTypes = null;
if(_serverChannel != null) {
if(Environment.UserInteractive) {
// LEF: Don't unregister the channel, because we are running from the service, and we don't want to unregister the channel...
ChannelServices.UnregisterChannel(_serverChannel);
// LEF: If we are coming from the SERVICE, we do *NOT* want to unregister the channel, since it is already registered!
_serverChannel = null;
}
}
bConnected = false;
}
}
So, THAT is meat of my remoting code, and allowed me to write a client that didn't have to be aware of where the services was installed, or how many services were running on the network. This allowed me to communicate with it over the network, or on the local machine. And it wasn't a problem to have two or more people running the app, however, yours might. Now, I have some complicated callback code in mine, where I register events to go across the remoting channel, so I have to have code that checks to see if the client is even still connected before I send the notification to the client that something happened. Plus, if you are running for more than one user, you might not want to use Singleton objects. It was fine for me, because the server OWNS the objects, and they are whatever the server SAYS they are. So, my STATS object, for example, is a Singleton. No reason to create an instance of it for EVERY connection, when everyone is going to see the same data, right?
I can provide more chunks of code if necessary. This is, of course, one TINY bit of the overall picture of what makes this work... Not to mention the subscription providers, and all that.
For the sake of completeness, I'm including the code chunk to keep your service connected for the life of the process.
public override object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if(lease.CurrentState == LeaseState.Initial) {
lease.InitialLeaseTime = TimeSpan.FromHours(24);
lease.SponsorshipTimeout = TimeSpan.FromSeconds(30);
lease.RenewOnCallTime = TimeSpan.FromHours(1);
}
return lease;
}
#region ISponsor Members
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
public TimeSpan Renewal(ILease lease)
{
return TimeSpan.FromHours(12);
}
#endregion
If you include the ISponsor interface as part of your server object, you can implement the above code.
Hope SOME of this is useful.
When you register your service, you can tell it to allow interactions with the desktop. You can read this oldie link http://www.codeproject.com/KB/install/cswindowsservicedesktop.aspx
Also, don't forget that you can have multiple users logged in at the same time.
Apparently on Windows Vista and newer interacting with the desktop has been made more difficult. Read this for a potential solution: http://www.codeproject.com/KB/cs/ServiceDesktopInteraction.aspx

Correct way to use databases in Windows 8 and Windows Phone 8

I am currently working on a Windows 8 app which needs to store some tables. Currently, I am using XML files with XDocument classes to solve the purpose. It employs save and load methods using GetFileAsync and CreateFileAsync etc. Moreover, there save and load methods are called by different events. However, whenever there are repeated calls, an exception is thrown telling me that file access is denied. Expected behavior - more details here! While there are dirty methods to avoid this (like using locks and such) I am not very happy with the results. I'd rather prefer databases. Moreover, I am planning to write another app for Windows Phone 8 (and possibly a web version) which will make use of the data.
They have been repeatedly saying that Windows 8 is cloud based. Now the question: What is correct way to store my data? XML seems right but is has problems I mentioned above. What would be ideal cloud based solution involving Windows 8, Windows Phone 8 and possibly Azure? All I want is to store tables and make those accessible.
Sorry if the question seems unclear. I will provide information if required.
If you want to use Azure, the easiest way to proceed is Windows Azure Mobile services. It allows you to setup your database and webservices using a web interface in a few minutes.
It's quite cool, allows you to add custom javascript to your web api logic, and generates json web apis. There are client Libraries for Windows 8, Windows Phone and iOS. You could easily roll your own for any http enabled frontends.
However be aware that taking the cloud route means that your app won't work offline, (if you don't code a cache system that is. And a cache will requires a local DB.)
About the local DB
You really have to possibilities:
1) A real DB in your app, like SQLite. It's available as a Nuget package but right now ARM support isn't available out of the box, nor guaranteed by the team. If you don't need arm, Go try it :)
2) plain old file storage, like you did before. I personally often do that myself. You will however get issues when accessing it from different threads (Access Denied errors).
When you store things in a local file, don't forget to lock the critical sections (ie when you read or write to the file) to prevent the access denied exceptions. To be sure, Incapsulate your write/read logic in a service class instance unique within your app. (Use the singleton pattern for instance, or anything equivalent).
The lock itself, now. I imagine that you are using async await. I like this sweet thing too. But classic C# locks (using the lock keyword for instance) don't work with async await. (And even if it worked, blocking wouldn't be cool).
That's why the marvellous AsyncLock comes into play. It's a lock, but which -approximately- doesn't block (you await it).
public class AsyncLock
{
private readonly AsyncSemaphore m_semaphore;
private readonly Task<Releaser> m_releaser;
public AsyncLock()
{
m_semaphore = new AsyncSemaphore(1);
m_releaser = Task.FromResult(new Releaser(this));
}
public Task<Releaser> LockAsync()
{
var wait = m_semaphore.WaitAsync();
return wait.IsCompleted ?
m_releaser :
wait.ContinueWith((_, state) => new Releaser((AsyncLock)state),
this, CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
public struct Releaser : IDisposable
{
private readonly AsyncLock m_toRelease;
internal Releaser(AsyncLock toRelease) { m_toRelease = toRelease; }
public void Dispose()
{
if (m_toRelease != null)
m_toRelease.m_semaphore.Release();
}
}
}
public class AsyncSemaphore
{
private readonly static Task s_completed = Task.FromResult(true);
private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>();
private int m_currentCount;
public AsyncSemaphore(int initialCount)
{
if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount");
m_currentCount = initialCount;
}
public Task WaitAsync()
{
lock (m_waiters)
{
if (m_currentCount > 0)
{
--m_currentCount;
return s_completed;
}
else
{
var waiter = new TaskCompletionSource<bool>();
m_waiters.Enqueue(waiter);
return waiter.Task;
}
}
}
public void Release()
{
TaskCompletionSource<bool> toRelease = null;
lock (m_waiters)
{
if (m_waiters.Count > 0)
toRelease = m_waiters.Dequeue();
else
++m_currentCount;
}
if (toRelease != null)
toRelease.SetResult(true);
}
}
you can use it this way (I suppose that you have an AsyncLock field named blogLock (taken from one of my own projects):
using (await blogLock.LockAsync())
{
using (var stream = await folder.OpenStreamForReadAsync(_blogFileName))
{
using (var reader = new StreamReader(stream))
{
var json = await reader.ReadToEndAsync();
var blog = await JsonConvert.DeserializeObjectAsync<Blog>(json);
return blog;
}
}
}
I've stumbled across this thread because I have basically the exact same problem. What seems staggering to me is that Microsoft makes its own enterprise-class database product (SQL Server), which already has a couple of lightweight, embeddable versions, and yet these seemingly can't be used with Windows 8/Windows Phone 8 applications to provide a local database. And yet MySQL can!
I've tried a couple of times to dabble in writing Windows Phone 8 apps, using my ASP.NET/VB/NET/SQL experience, but I always get bogged down in trying to learn a different way to perform data operations that I can do in my sleep in a web environment and lose interest. Why can't they make it easy to use SQL with W8/WP8 apps?
If the data pertains to the user of the device look at using SQLlite ... there is a question on Stack about SQLlite and local winRT Databases here: Local database storage for WinRT/Metro applications
SQL Databases
IndexedDB incase of the Windows 8 and JavaScript development
I know this is an old question that already has an accepted answer, but I'm going to get out my soapbox and answer it anyway because I think that rather than solve the technical problem it is better to use an architecture that doesn't depend on local database facilities.
In my experience very little data requires device local database services.
Most user generated data requiring local storage is non-roaming (ie device specific) user preferences and configuration (eg use removable storage setting). Game results fall into this category. Apps that produce larger quantities of user data are typically implemented on the desktop and almost certainly have a fast reliable connection to the local network, making server-based storage eminently suitable even for "fat" data like Office documents.
Reference data should certainly be server based, but you might choose to cache it. Nokia Maps on Windows Phone 8 is an excellent example of cached server-based data. The cache can even be explicitly pre-loaded in anticipation of off-line use.
The world view I have just expounded has little use for a local SQL Server. If you want a query engine, use LINQ. Express your application settings and user data as an object graph and (de)serialise XML. You could even use Linq2Xml directly on the XML if you don't want to maintain ORM classes.
Data of any sort that ought to be available across all the user's devices really needs to be cloud stored anyway.
To address some of akshay's comments,
Map data
Geospatial data is typically organised into structures known as quad-trees for a variety of reasons broadly to do with providing a level of detail that varies with zoom. The way these are accessed and manipulated derives considerable advantage from their representation as object graphs, and they are not updated by the users, so while this data certainly could be stored in a relational database and it probably is while it's being compiled, it certainly isn't stored or delivered that way.
LINQ is well adapted to this scenario because it can be applied directly to the quad-tree.
The data certainly is in a file. But I imagine you meant direct file access rather than indirection through another process. Probably the thought in your mind is that it is a good idea to invest significant effort on thoroughly solving the problems of concurrency and query processing once and share the solution between client apps. But this is a very heavyweight solution, and the query processing aspect is already well handled by LINQ (which is why I keep mentioning it).
Your XML problems
Read-only doesn't need to lock, so avoid the file system locking problem by caching and using Singleton pattern...
public static class XManager
{
static Dictionary<string, XDocument> __cache = new Dictionary<string, XDocument>();
public static XDocument GetXDoc(string filepath)
{
if (!__cache.Contains(filepath)
{
__cache[filepath] = new XDocument();
__cache[filepath].Load(filepath);
}
return _cache[filepath];
}
}

Which Communication technique is better for talking between two applications

C#WinForms: There are a couple of ways for two applications to talk together, I am not very knowledgeable in this area but things like MSMQ and Named Pipes comes to my mind but not sure what is the best. So here is the scenario, what do you think is the best approach:
Let's say I write a windows service that backs up some files to somewhere on occasion.
User opens some my Application XYX and I want him to be notified that hey there is new backup file for you over there.
That's all. This was the scenario.
Use MSMQ as it is very simple to implement and you could play with objects. Producer and Consumer then can interact with each other very simply.These two applications(Producer, COnsumer) can be on the same machine, across a network, or even on different machines that aren't always connected. MSMQ is considered failsafe in that it will retry sending a message if the first transmission fails. This allows you to be very confident that your application messages will arrive at their destination.
More Details
We just used Named Pipes for a similar purpose on a recent project. Code turned out to be really simple. I can't claim credit for this particular code but here it is:
/// <summary>
/// This will attempt to open a service to listen for message requests.
/// If the service is already in use it means that another instance of this WPF application is running.
/// </summary>
/// <returns>false if the service is already in use by another WPF instance and cannot be opened; true if the service sucessfully opened</returns>
private bool TryOpeningTheMessageListener()
{
try
{
NetNamedPipeBinding b = new NetNamedPipeBinding();
sh = new ServiceHost(this);
sh.AddServiceEndpoint(typeof(IOpenForm), b, SERVICE_URI);
sh.Open();
return true;
}
catch (AddressAlreadyInUseException)
{
return false;
}
}
private void SendExistingInstanceOpenMessage(int formInstanceId, int formTemplateId, bool isReadOnly, DateTime generatedDate, string hash)
{
try
{
NetNamedPipeBinding b = new NetNamedPipeBinding();
var channel = ChannelFactory<IOpenForm>.CreateChannel(b, new EndpointAddress(SERVICE_URI));
channel.OpenForm(formInstanceId, formTemplateId, isReadOnly, generatedDate, hash);
(channel as IChannel).Close();
}
catch
{
MessageBox.Show("For some strange reason we couldnt talk to the open instance of the application");
}
}
In our OnStartup we just had
if (TryOpeningTheMessageListener())
{
OpenForm(formInstanceId, formTemplate, isReadOnly, generatedDate, hash);
}
else
{
SendExistingInstanceOpenMessage(formInstanceId, formTemplate, isReadOnly, generatedDate, hash);
Shutdown();
return;
}
There are many ways to achieve what you have asked;
As Damith said make an entry to database and read from it.
Make an entry in a file and read from it.
Use WCF - Windows Communication Foundation and set the configuration to use the MSMQ bindings. Read WCF & MSMQ article to get you started.

in c#.net how to send message to remote computer throught internet?

c#.net framework 4.0 client profile,Windows application..
i am developing a game which needs to send its current movements of the game through internet to remote computer where the same application(game) is installed.In Same way current movements of the game of remote computer should be send back...
How this could be possible ?
All the answers so far are using a TCP based approach. If you need high performance and low latency then you might find it better to use UDP instead.
TCP brings a lot of overhead with it to guarantee that packets will be resent if they are lost (and various other bits of functionality). UDP on the other hand leaves it up to you to deal with packets not arriving. If you have a game where losing the odd update isn't important you can achieve far better bandwidth use, latency and scalability by using UDP instead of TCP.
UDP still leaves you with all the issues of firewalls, security etc though.
If you need to have it work without worrying about firewalls being an issue then you want to choose a solution that uses HTTP over port 80.
To do that you need to implement a client-server behavior through TCP/IP
There are very different ways to do this
This code I've written could give you a start (it's an option, but not the only one, I leave it off to you to choose the method that suits you best)
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
static class ServerProgram
{
[STAThread]
static void Main()
{
ATSServer();
}
static void ATSServer()
{
TcpChannel tcpChannel = new TcpChannel(7000);
ChannelServices.RegisterChannel(tcpChannel);
Type commonInterfaceType = Type.GetType("ATSRemoteControl");
RemotingConfiguration.RegisterWellKnownServiceType(commonInterfaceType,
"RemoteATSServer", WellKnownObjectMode.SingleCall);
}
}
public interface ATSRemoteControlInterface
{
string yourRemoteMethod(string parameter);
}
public class ATSRemoteControl : MarshalByRefObject, ATSRemoteControlInterface
{
public string yourRemoteMethod(string GamerMovementParameter)
{
string returnStatus = "GAME MOVEMENT LAUNCHED";
Console.WriteLine("Enquiry for {0}", GamerMovementParameter);
Console.WriteLine("Sending back status: {0}", returnStatus);
return returnStatus;
}
}
class ATSLauncherClient
{
static ATSRemoteControlInterface remoteObject;
public static void RegisterServerConnection()
{
TcpChannel tcpChannel = new TcpChannel();
ChannelServices.RegisterChannel(tcpChannel);
Type requiredType = typeof(ATSRemoteControlInterface);
//HERE YOU ADJUST THE REMOTE TCP/IP ADDRESS
//IMPLEMENT RETRIEVAL PROGRAMATICALLY RATHER THAN HARDCODING
remoteObject = (ATSRemoteControlInterface)Activator.GetObject(requiredType,
"tcp://localhost:7000/RemoteATSServer");
string s = "";
s = remoteObject.yourRemoteMethod("GamerMovement");
}
public static void Launch(String GamerMovementParameter)
{
remoteObject.yourRemoteMethod(GamerMovementParameter);
}
}
Hope this Helps.
You should look into some middleware teknologies like WCF, Web service
this is object oriented and easy to develop when you first get the hang of it
You have a lot to consider for this.
You will need to think about security, firewall issues etc.
If that is all put to one side, then you can set up a tcp socket server / client approach.
A quick google will yield plenty of examples.
Check out the Microsoft example http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx
What have you tried?
You can use the System.Net and System.Net.Sockets namespaces to send TCP packets.

Categories