[en] How to restart Server without restart the Applikation? (solved)

Topics: Technical Support
Feb 27 at 3:55 PM
Hi,

If i stop the Server with:
this.ZyanHost.UnregisterComponent("MyComponent");
            
this.ZyanHost.Dispose();
and then restart it, i got a socket error:
Only one usage of each socket address (protocol/network address/port) is normally permitted

System.Net.Sockets.SocketException wurde nicht behandelt.
Message: Ein Ausnahmefehler des Typs "System.Net.Sockets.SocketException" ist in System.dll aufgetreten.
Zusätzliche Informationen: Normalerweise darf jede Socketadresse (Protokoll, Netzwerkadresse oder Anschluss) nur jeweils einmal verwendet werden
What do i wrong?
How i can stop and start the server?

Thx for any help.
Coordinator
Feb 28 at 2:50 PM
Hello iPanic,

disposing of the host should be enough to stop the server and free up the TCP port.
There is no need to unregister components, just call host.Dispose(), and that's all.

I can't reproduce the problem on my side.
What protocol are you using?

Here is my example code that starts and stops the server twice in a row:
using System;
using Zyan.Communication;

class Program
{
    static void Main()
    {
        TestPingPong();
        TestPingPong();
    }

    static void TestPingPong()
    {
        Console.WriteLine("-----------------------------");

        var host = new ZyanComponentHost("Ping", 8765);
        host.RegisterComponent<IPing, PingService>();
        Console.WriteLine("Started server: {0}", host.DiscoverableUrl);

        using (var conn = new ZyanConnection("tcp://localhost:8765/Ping"))
        {
            var ping = conn.CreateProxy<IPing>();
            var pong = ping.Ping("Ping");
            Console.WriteLine("Server call result: [{0}].", pong);
        }

        host.Dispose();
        Console.WriteLine("Stopped server.");
    }

    public interface IPing
    {
        string Ping(string t);
    }

    class PingService : IPing
    {
        public string Ping(string t)
        {
            return "Pong: " + t;
        }
    }
}
The code doesn't throw exceptions and outputs the following:
-----------------------------
Started server: tcp://192.168.59.3:8765/Ping
Server call result: [Pong: Ping].
Stopped server.
-----------------------------
Started server: tcp://192.168.59.3:8765/Ping
Server call result: [Pong: Ping].
Stopped server.
Please modify this code sample so it produces the error.

Regards, Alex.
Feb 28 at 3:19 PM
Hello Alex,

i am using TcpDuplex.

But i cant test it, i got always a exception :
Zyan.Communication.ChannelSinks.Encryption.CryptoRemotingException wurde nicht behandelt.
  HResult=-2146233077
  Message=Der Schlüssel wurde seit dem verschlüsseln der Nachricht geändert.
  Source=Zyan.Communication
  StackTrace:
    Server stack trace: 
       bei Zyan.Communication.ChannelSinks.Encryption.CryptoClientChannelSink.ProcessSharedKeyResponse(ITransportHeaders responseHeaders) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Encryption\CryptoClientChannelSink.cs:Zeile 169.
       bei Zyan.Communication.ChannelSinks.Encryption.CryptoClientChannelSink.ObtainSharedKey(IMessage msg) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Encryption\CryptoClientChannelSink.cs:Zeile 108.
       bei Zyan.Communication.ChannelSinks.Encryption.CryptoClientChannelSink.StartSecureTransaction(IMessage msg, ITransportHeaders requestHeaders) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Encryption\CryptoClientChannelSink.cs:Zeile 83.
       bei Zyan.Communication.ChannelSinks.Encryption.CryptoClientChannelSink.ProcessEncryptedMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Encryption\CryptoClientChannelSink.cs:Zeile 0.
       bei Zyan.Communication.ChannelSinks.Encryption.CryptoClientChannelSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Encryption\CryptoClientChannelSink.cs:Zeile 258.
       bei Zyan.Communication.ChannelSinks.Compression.CompressionClientChannelSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream) in D:\Externals\Zyan\source\Zyan.Communication\ChannelSinks\Compression\CompressionClientChannelSink.cs:Zeile 175.
       bei System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
    Exception rethrown at [0]: 
       bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       bei Zyan.Communication.IZyanDispatcher.Logon(Guid sessionID, Hashtable credentials)
       bei Zyan.Communication.ZyanConnection..ctor(String serverUrl, IClientProtocolSetup protocolSetup, Hashtable credentials, Boolean autoLoginOnExpiredSession, Boolean keepSessionAlive) in D:\Externals\Zyan\source\Zyan.Communication\ZyanConnection.cs:Zeile 228.
       bei Zyan.Communication.ZyanConnection..ctor(String serverUrl, IClientProtocolSetup protocolSetup, Hashtable credentials, Boolean autoLoginOnExpiredSession, Boolean keepSessionAlive) in D:\Externals\Zyan\source\Zyan.Communication\ZyanConnection.cs:Zeile 240.
       bei Zyan.Communication.ZyanConnection..ctor(String serverUrl, IClientProtocolSetup protocolSetup) in D:\Externals\Zyan\source\Zyan.Communication\ZyanConnection.cs:Zeile 135.
       bei ZyanTest.Program.TestPingPong() in D:\CloudStation\dotNet\Projekte\Work\Zyan_test\ZyanTest\Program.cs:Zeile 29.
       bei ZyanTest.Program.Main() in D:\CloudStation\dotNet\Projekte\Work\Zyan_test\ZyanTest\Program.cs:Zeile 15.
       bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
    class Program
    {
        static void Main()
        {
            TestPingPong();
            TestPingPong();
        }

        static void TestPingPong()
        {
            Console.WriteLine("-----------------------------");



            var host = new ZyanComponentHost("Ping", new Zyan.Communication.Protocols.Tcp.TcpDuplexServerProtocolSetup(8765));
            host.RegisterComponent<IPing, PingService>();
            Console.WriteLine("Started server: {0}", host.DiscoverableUrl);

            using (var conn = new ZyanConnection("tcpex://localhost:8765/Ping", new Zyan.Communication.Protocols.Tcp.TcpDuplexClientProtocolSetup()))
            {
                var ping = conn.CreateProxy<IPing>();
                var pong = ping.Ping("Ping");
                Console.WriteLine("Server call result: [{0}].", pong);
            }

            host.Dispose();
            Console.WriteLine("Stopped server.");
        }

        public interface IPing
        {
            string Ping(string t);
        }

        class PingService : IPing
        {
            public string Ping(string t)
            {
                return "Pong: " + t;
            }
        }
    }
Coordinator
Feb 28 at 10:34 PM
Edited Feb 28 at 10:56 PM
Hi iPanic,

now I see. It's most likely a bug in TcpDuplex channel.
The channel should close the listener socket when the host is disposed of.
Standard TcpChannel works as expected while TcpDuplex channel doesn't seem to shut down properly.

I'll file an issue about the problem.
Thank you for the report!

Regards, Alex
Coordinator
Feb 28 at 10:54 PM
Edited Feb 28 at 11:02 PM
Wait, I'm completely wrong, sorry.

There was a problem with my example code. It's fine for plain TcpChannel, but it's not ok for TcpDuplex.
TcpDuplex channel cannot act both as a client and a server inside the same application domain.
I should have paid more attention to the exception message, but I can't read German, sorry.

I modified my code so it runs the client part in a separate application domain, and it works fine.
The server starts up and shuts down twice in a row without any problems.
Please have a look:
using System;
using Zyan.Communication;

class Program
{
    static void Main()
    {
        TestPingPong();
        TestPingPong();
    }

    static void TestPingPong()
    {
        Console.WriteLine("-----------------------------");

        var protocol = new Zyan.Communication.Protocols.Tcp.TcpDuplexServerProtocolSetup(8765);
        var host = new ZyanComponentHost("Ping", protocol);
        host.RegisterComponent<IPing, PingService>();
        Console.WriteLine("Started server: {0}", host.DiscoverableUrl);

        // client code for TcpDuplex cannot be run in the same application domain 
        var clientAppDomain = AppDomain.CreateDomain("ClientAppDomain");
        var clientDelegate = new CrossAppDomainDelegate(RunClient);
        clientAppDomain.DoCallBack(clientDelegate);

        host.Dispose();
        Console.WriteLine("Stopped server.");
    }

    static void RunClient()
    {
        using (var conn = new ZyanConnection("tcpex://localhost:8765/Ping"))
        {
            var ping = conn.CreateProxy<IPing>();
            var pong = ping.Ping("Ping");
            Console.WriteLine("Server call result: [{0}].", pong);
        }
    }

    public interface IPing
    {
        string Ping(string t);
    }

    class PingService : IPing
    {
        public string Ping(string t)
        {
            return "Pong: " + t;
        }
    }
}
The output is like this:
-----------------------------
Started server: tcpex://192.168.1.101:8765/Ping
Server call result: [Pong: Ping].
Stopped server.
-----------------------------
Started server: tcpex://192.168.1.101:8765/Ping
Server call result: [Pong: Ping].
Stopped server.
Feb 29 at 8:11 AM
Hi Alex,

when I start it I get:
 at the second run of:   var host = new ZyanComponentHost("Ping", protocol);

System.Net.Sockets.SocketException wurde nicht behandelt.
  ErrorCode=10048
  HResult=-2147467259
  Message=Normalerweise darf jede Socketadresse (Protokoll, Netzwerkadresse oder Anschluss) nur jeweils einmal verwendet werden
  NativeErrorCode=10048
  Source=System
  StackTrace:
       bei System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
       bei System.Net.Sockets.Socket.Bind(EndPoint localEP)
       bei Zyan.Communication.Protocols.Tcp.DuplexChannel.Manager.StartListening(Int32 port, TcpExChannel channel, IPAddress bindToAddress) in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\DuplexChannel\Manager.cs:Zeile 193.
       bei Zyan.Communication.Protocols.Tcp.DuplexChannel.TcpExChannel.StartListening(Object data) in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\DuplexChannel\TcpExChannel.cs:Zeile 408.
       bei Zyan.Communication.Protocols.Tcp.DuplexChannel.TcpExChannel.Initialise(TypeFilterLevel typeFilterLevel, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider, Int32 port, Boolean listen, Boolean keepAlive, UInt64 keepAliveTime, UInt64 KeepAliveInterval, Int16 maxRetries, Int32 retryDelay, IPAddress bindToAddress) in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\DuplexChannel\TcpExChannel.cs:Zeile 227.
       bei Zyan.Communication.Protocols.Tcp.DuplexChannel.TcpExChannel..ctor(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider) in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\DuplexChannel\TcpExChannel.cs:Zeile 192.
       bei Zyan.Communication.Protocols.Tcp.TcpDuplexServerProtocolSetup.<.ctor>b__3(IDictionary settings, IClientChannelSinkProvider clientSinkChain, IServerChannelSinkProvider serverSinkChain) in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\TcpDuplexServerProtocolSetup.cs:Zeile 75.
       bei Zyan.Communication.Protocols.Tcp.TcpDuplexServerProtocolSetup.CreateChannel() in D:\Externals\Zyan\source\Zyan.Communication\Protocols\Tcp\TcpDuplexServerProtocolSetup.cs:Zeile 425.
       bei Zyan.Communication.ZyanComponentHost.StartListening() in D:\Externals\Zyan\source\Zyan.Communication\ZyanComponentHost.cs:Zeile 303.
       bei Zyan.Communication.ZyanComponentHost..ctor(String name, IServerProtocolSetup protocolSetup, ISessionManager sessionManager, ComponentCatalog catalog) in D:\Externals\Zyan\source\Zyan.Communication\ZyanComponentHost.cs:Zeile 121.
       bei Zyan.Communication.ZyanComponentHost..ctor(String name, IServerProtocolSetup protocolSetup) in D:\Externals\Zyan\source\Zyan.Communication\ZyanComponentHost.cs:Zeile 59.
       bei ZyanTest.Program.TestPingPong() in C:\Users\chris_000\CloudStation\dotNet\Projekte\Work\Zyan_test\ZyanTest\Program.cs:Zeile 26.
       bei ZyanTest.Program.Main() in C:\Users\chris_000\CloudStation\dotNet\Projekte\Work\Zyan_test\ZyanTest\Program.cs:Zeile 18.
       bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
Coordinator
Feb 29 at 10:16 AM
What version of Zyan are you using?

Please try building the library from the latest SVN sources.
Nuget package is a bit outdated...

Regards, Alex
Marked as answer by yallie on 2/29/2016 at 12:38 PM
Feb 29 at 8:33 PM
I am using V2.6 from Nugte.

but with the last svn build, it works!

Thank you!

Can i use the svn build in a productive environment? Is it stabe?
Coordinator
Feb 29 at 8:37 PM
Hi, thanks for confirming that!

Yes, SVN version passes the same unit tests and can be used in production.
It's in fact used in production in our company.

I am going to publish a Nuget package with a signed assembly in the near future.

Regards, Alex