Forum Replies Created
-
AuthorPosts
-
MarcFKeymaster
Heya IZZO, welcome to our forums and many thanks for your interest in our network library.
Ok, so the general idea of establish and close handlers is that you can trigger some code when a connection is established or closed.
If we define the following two methods:
static void ClientConnected(Connection connection) { Console.WriteLine("A new client connected - " + connection.ToString()); } static void ClientDisconnected(Connection connection) { Console.WriteLine("A client has disconnected - " + connection.ToString()); }
all they do is write some text to a console window. You could perform whatever you want.
We can then tell NetworkComms what to do with these, either on a global level, so that the methods are executed for all connections:
NetworkComms.AppendGlobalConnectionEstablishHandler(ClientConnected); NetworkComms.AppendGlobalConnectionCloseHandler(ClientDisconnected);
or on a connection specific level:
Connection newConnection = TCPConnection.GetConnection(new ConnectionInfo("127.0.0.1", 10000)); newConnection.AppendShutdownHandler(ClientDisconnected);
There is no connection specific establish handler method because it would be superfluous.
Hope that’s what you were after, if not please let me know which bit you are unsure about.
Marc
MarcFKeymasterok, you are on the latest version and .net2 is probably the best build for MT.
The exception is not the most useful as it doesn’t really point to exactly where the problem is caused. That’s the joy of mono, sometimes you just get to guess
There is only really one place we use reflection in the library and that is to auto detect available serialisers and data processors. We already catch some exception cases and default to an older, less efficient method in those cases. We didn’t add a global catch all as we were interested to know what other failure modes we had not found. This may be one of them.
I have added a new catch for ‘MissingMethodException’ and uploaded a beta DLL which you can tryout from https://networkcomms.net/downloads/NetworkCommsDotNet_v2.2.1_Beta_Net2CompleteDLL.zip.
If this solves the problem I will include it with the release of 2.2.1 so let me know how you get on.
If you continue to have issues or other questions just let us know and we’ll do our best to sort them.
Regards,
MarcMarcFKeymasterHey micjames,
Welcome to our forums and many thanks for your interest in NetworkComms.Net. I assume you are using the latest version, 2.2? Also, which .net version is the DLL are you trying to use in MT? If you could give me that info as well as a full exception / stack trace of the error that should get us on the right road to a solution.
Regards,
Marc
MarcFKeymasterJust to update. We have now released v2.2.0. If you use the .net2.0 build all features should be working.
Thanks again.
MarcFKeymasterHeya Sp1rit,
Thanks for your interest in NetworkComms.Net. Setting up a progress bar is relatively straight forward. You are already on the right track with the StreamSendWrapper, a short example that should get you going is as follows:
On the client side you break the send into multiple instances using ThreadSafeStream and StreamSendWrapper.
//This is our progress percent, between 0 and 1 double progressPercentage = 0; //Initialise stream with 1MB byte[] buffer = new byte[1024*1024]; DPSBase.ThreadSafeStream dataToSend = new DPSBase.ThreadSafeStream(new System.IO.MemoryStream(buffer)); int totalBytesSent = 0; //We will send in chunks of 50KB int sendInChunksOfNBytes = 50 * 1024; //Get the connection to the target Connection connection = TCPConnection.GetConnection(new ConnectionInfo("192.168.0.1", 10000)); do { //Determine the total number of bytes to send //We need to watch out for the end of the buffer when we send less than sendInChunksOfNBytes int bytesToSend = (buffer.Length - totalBytesSent > sendInChunksOfNBytes ? sendInChunksOfNBytes : buffer.Length - totalBytesSent); DPSBase.StreamSendWrapper streamWrapper = new DPSBase.StreamSendWrapper(dataToSend, totalBytesSent, bytesToSend); connection.SendObject("PartitionedSend", streamWrapper); totalBytesSent+=bytesToSend; progressPercentage = ((double)totalBytesSent / buffer.Length); } while (totalBytesSent < buffer.Length);
On the server side you just reassemble the stream as the data comes in:
System.IO.Stream recievedData = new System.IO.MemoryStream(); NetworkComms.AppendGlobalIncomingPacketHandler<byte[]>("PartitionedSend", (packetHeader, connection, incomingBytes) => { Console.WriteLine("\n ... Incoming data from " + connection.ToString()); recievedData.Write(incomingBytes, 0, incomingBytes.Length); });
If you have any issues just post back.
Marc
MarcFKeymasterHeyup,
It’s tough to follow exactly what you are doing but a couple of notes:
1. Setting networkComms.net up like this can be dangerous as you are potentially trying to receive two different objects using the some incoming packetType.
// Incoming data callback NetworkComms.AppendGlobalIncomingPacketHandler("CustomObject", incomingData); NetworkComms.AppendGlobalIncomingPacketHandler("CustomObject", incomingData2);
2. Check your run time folder for potential error log messages.
3. If you want to step through the conversion, incoming raw bytes are converted back to objects by the methods:
Connection.TriggerSpecificPacketHandlers(); NetworkComms.TriggerGlobalPacketHandlers();
4. If you want the server to simply be forwarding data without the need for the server to understand it it will be much more efficient to use the following structure. The main advantage of this approach is that you never have to change anything on the server as you add new classes to the clients.
Declare the following objects:
[ProtoContract] public class ClientObject { [ProtoMember(1)] public string ClientMessage { get; set; } private ClientObject() { } public ClientObject(string clientMessage) { this.ClientMessage = clientMessage; } } [ProtoContract] public class ServerForward { [ProtoMember(1)] public string ClientIPAddress { get; set; } [ProtoMember(2)] public int ClientPort { get; set; } [ProtoMember(3)] public string PacketType { get; set; } [ProtoMember(4)] public byte[] ForwardObjectBytes { get; set; } private ServerForward() { } public ServerForward(string clientIPAddress, int clientPort, string packetType, byte[] forwardObjectBytes) { this.ClientIPAddress = clientIPAddress; this.ClientPort = clientPort; this.PacketType = packetType; this.ForwardObjectBytes = forwardObjectBytes; } }
Configure the server with the following packet handler:
NetworkComms.AppendGlobalIncomingPacketHandler<ServerForward>("ServerForward", (connection, header, serverForward) => { Console.WriteLine("Recieved server forward object from " + connection); TCPConnection.GetConnection(new ConnectionInfo(serverForward.ClientIPAddress, serverForward.ClientPort)).SendObject(serverForward.PacketType, serverForward.ForwardObjectBytes); });
The sending client uses the following:
ClientObject clientObject = new ClientObject("this is a forwarded client object"); ServerForward serverForward = new ServerForward("192.168.0.10",10000, "ClientObjectRaw", DPSManager.GetDataSerializer<ProtobufSerializer>().SerialiseDataObject<ClientObject>(clientObject).ThreadSafeStream.ToArray()); TCPConnection.GetConnection(new ConnectionInfo(serverIP, serverPort)).SendObject("ServerForward", serverForward);
The receiving client uses the following:
NetworkComms.AppendGlobalIncomingPacketHandler<byte[]>("ClientObjectRaw", (connection, header, rawBytes) => { ClientObject incomingClientObject = DPSManager.GetDataSerializer<ProtobufSerializer>().DeserialiseDataObject<ClientObject>(rawBytes); Console.WriteLine("Server forwarded client object which says + " incomingClientObject.ClientMessage); });
MarcFKeymasterOk, all Unity3D issues have now been fixed and will be in the v2.2 network library release.
MarcFKeymasterWhen you say object in object, would something like this be suitable:
[ProtoContract] public class ClientInfo { [ProtoMember(1)] string ClientMessage { get; set; } private ClientInfo() { } public ClientInfo(string clientMessage) { this.ClientMessage = clientMessage; } } [ProtoContract] public class ServerInfo { [ProtoMember(1)] public ClientInfo ClientInfo {get; set;} [ProtoMember(2)] public string ServerMessage { get; set; } private ServerInfo() { } public ServerInfo(ClientInfo clientInfo, string serverMessage) { this.ClientInfo = clientInfo; this.ServerMessage = serverMessage; } }
MarcFKeymasterAh, you are not using the correct method.
You are using
conn = new UDPConnection(conninfo, UDPOptions.None);
you should be using
conn = UDPConnection.GetConnection(conninfo, UDPOptions.None);
note, this is a static method so no ‘new’ statement. It’s implemented in this was so that if a connection already exists with the provided connectionInfo the existing connection can be returned instead.
Marc
MarcFKeymasterHeya Whippets, documentation on all of networkComms.Net should be available via either the online API, https://networkcomms.net/api/ or the downloadable reference, https://networkcomms.net/download/.
Exactly which method is throwing the error “doesn’t contain a constructer that takes 2 arguments”? Also what development environment are you using, i.e. monodevelop, visual studio 2005 express, visual studio 2012 ultimate etc?
-
AuthorPosts