none
ASP.Net MVC + SignalR invoke WCF using wsDualHttpBinding (or netTcpBinding) RRS feed

  • Question

  • I have a standalone Application which is using WCF with wsDualHttpBinding. This standalone application will randomly send message to any client which has subscribed the service by using the callback behavior of wsDualHttpBinding in WCF.

    The application subscribe and callback behavior is worked successfully if I use a window application (WPF) as a client.

    Then I want to create an ASP.Net MVC application which use SignalR as server push and subscribe the service provided by the above standalone application. When message come back from the application, I will use SignalR to push the message and display it in browser.

    However, when tried to create such ASP.Net application, whenever the message callback from the standalone Application, the ASP.Net application will be shutdown.

    The following is the code for the hub of SignalR:

    public class MessageSubcriberHub : Hub
        {
            private static readonly Dictionary<string, MessageSubcriber> Subcribers = new Dictionary<string, MessageSubcriber>();
    
            public bool Subcribe()
            {
                if (Subcribers.Keys.Contains(Context.ConnectionId))
                {
                    return true;
                }
                try
                {
                    MessageSubcriber sub = new MessageSubcriber();
                    sub.ConnectionId = Context.ConnectionId;
                    if (sub.Subcribe())
                    {
                        sub.listener += (string message, DateTime time) =>
                        {
                            try
                            {
                                var context = GlobalHost.ConnectionManager.GetHubContext<MessageSubcriberHub>();
                                context.Clients.Client(sub.ConnectionId).MessageReceived(message, time);
                            }
                            catch
                            {
                                if (Subcribers.Keys.Contains(sub.ConnectionId))
                                {
                                    Subcribers.Remove(sub.ConnectionId);
                                }
                            }
                        };
                        Subcribers.Add(Context.ConnectionId, sub);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
    
            public bool Unsubcribe()
            {
                if (Subcribers.Keys.Contains(Context.ConnectionId))
                {
                    try
                    {
                        Subcribers[Context.ConnectionId].Dispose();
                        Subcribers.Remove(Context.ConnectionId);
                        return true;
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
                return true;
            }
    
            public override Task OnDisconnected()
            {
                //return Clients.All.leave(Context.ConnectionId, DateTime.Now.ToString());
                return new Task(new Action(()=>{
                    if (Subcribers.Keys.Contains(Context.ConnectionId))
                    {
                        try
                        {
                            Subcribers[Context.ConnectionId].Dispose();
                            Subcribers.Remove(Context.ConnectionId);
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }));
            }
    
    
        }


    WCF callback handler:

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
        public class MessageSubcriber : IMessagingServiceCallback, IDisposable
        {
            public string ConnectionId { get; set; }
    
            MessagingServiceClient client;
            public delegate void MessageReceivedListener(string message, DateTime time);
    
            public event MessageReceivedListener listener;
    
            public MessageSubcriber()
            {
                InstanceContext context = new InstanceContext(this);
                client = new MessagingServiceClient(context, "WSDualHttpBinding_IMessagingService");
            }
    
            public bool Subcribe()
            {
                return client.Subscribe();
            }
    
            public bool Unsubcribe()
            {
                return client.Unsubscribe();
            }
    
            public virtual void MessageReceived(string message, DateTime time)
            {
                if (listener != null)
                {
                    listener.Invoke(message, time);
                }
            }
    
            public void Dispose()
            {
                client.Close();
            }
        }


    Client side WCF config:

    <system.serviceModel>
        <bindings>
          <wsDualHttpBinding>
            <binding name="WSDualHttpBinding_IMessagingService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <reliableSession ordered="true" inactivityTimeout="00:10:00" />
              <security mode="Message">
                <message clientCredentialType="Windows" negotiateServiceCredential="true"
                    algorithmSuite="Default" />
              </security>
            </binding>
          </wsDualHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://localhost:9999/MessagingService/" binding="wsDualHttpBinding"
              bindingConfiguration="WSDualHttpBinding_IMessagingService"
              contract="MessagingService.IMessagingService" name="WSDualHttpBinding_IMessagingService">
            <identity>
              <dns value="localhost" />
            </identity>
          </endpoint>
        </client>
      </system.serviceModel>


    Error Message from Event Viewer:

    <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="ASP.NET 4.0.30319.0" /> <EventID Qualifiers="49152">1325</EventID> <Level>2</Level> <Task>0</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2013-01-27T07:13:03.000000000Z" /> <EventRecordID>16208</EventRecordID> <Channel>Application</Channel> <Computer>Stanley-PC</Computer> <Security /> </System> <EventData> <Data> An unhandled exception occurred and the process was terminated. Application ID: 6ccca6be Process ID: 4964 Exception: System.Runtime.FatalException Message: Object reference not set to an instance of an object. StackTrace: at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result) at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item) at System.Runtime.InputQueue`1.Dispatch() at System.ServiceModel.Channels.ReliableDuplexSessionChannel.ProcessDuplexMessage(WsrmMessageInfo info) at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.ProcessMessage(WsrmMessageInfo info) at System.ServiceModel.Channels.ReliableDuplexSessionChannel.HandleReceiveComplete(IAsyncResult result) at System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnReceiveCompletedStatic(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) at System.ServiceModel.Channels.ReliableChannelBinder`1.InputAsyncResult`1.OnInputComplete(IAsyncResult result) at System.ServiceModel.Channels.ReliableChannelBinder`1.InputAsyncResult`1.OnInputCompleteStatic(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) at System.ServiceModel.Channels.FramingDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(Object state) at System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(Object state) at System.ServiceModel.Channels.StreamConnection.OnRead(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Security.NegotiateStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.NegotiateStream.ReadCallback(AsyncProtocolRequest asyncRequest) at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result) at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes) at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) at System.ServiceModel.Channels.ConnectionStream.ReadAsyncResult.OnAsyncReadComplete(Object state) at System.ServiceModel.Channels.SocketConnection.FinishRead() at System.ServiceModel.Channels.SocketConnection.AsyncReadCallback(Boolean haveResult, Int32 error, Int32 bytesRead) at System.ServiceModel.Channels.OverlappedContext.CompleteCallback(UInt32 error, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) InnerException: System.NullReferenceException Message: Object reference not set to an instance of an object. StackTrace: at System.Web.HttpApplication.ThreadContext.Enter(Boolean setImpersonationContext) at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext) at System.Web.AspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state) at System.Web.AspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state) at System.Web.AspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state) at System.ServiceModel.Dispatcher.ThreadBehavior.BindCore(MessageRpc& rpc, Boolean startOperation) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) </Data> </EventData> </Event>

    System Overview:

    Could the above problem be solved?


    Stanley


    • Edited by Stanleyabcd Monday, January 28, 2013 7:26 AM
    Monday, January 28, 2013 7:24 AM

All replies

  • Hi, Suggest you configure tracing for your service to get internal error message. 

    http://blog.devscrum.net/2011/12/getting-started-with-signalr-in-asp-net-mvc/

    Wednesday, January 30, 2013 5:26 AM
  • Hi Stanley,

    have you been able to solve the problem?

    I'm facing a similar issue with signalR and a Duplex WCF Service.

    Thanks a lot!

    Best Regards

    Markus

    Thursday, September 5, 2013 7:33 AM