Connecting to Dorico 5 API

I’m trying to connect to Dorico Pro 5.1.81 to use the Remote Control API. I’ve setup Scott Janssens Dorico.Net C# library in Visual Studio Code but it won’t connect to Dorico. I’m get the errors:

—> System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server
—> System.Net.Http.HttpRequestException: Connection refused (localhost:4560)

I’ve also tried 127.0.0.1:4560 with the same result.

Is it my windows 11 setup? Dorico setup or something else that is preventing the connection?

thanks

Check your firewall settings. Make sure you allow traffic (open) port 4560.

Thanks derAbgang for the suggestion but it made no difference. Wouldn’t this only affect connections to an external system? I’m trying to make a connection entirely locally, i.e. both client and server are running on the same machine.

Firewalls affect both internal and external FYI. But I’m wondering if you checked Dorico’s preferences and have enabled remote connections ?

Good thinking! I checked but the Remote Control is enabled and the port number’s the same, 4560.

Thanks for the heads up re firewalls, too.

You can also check that Dorico is indeed listening on that port for connections. Try
netstat -na | findstr /i "4560"
at a command prompt (as Administrator).

The Resource Monitor also has a “Listening Ports” section at the bottom of the Network tab.

A little simpler, from a PowerShell prompt: tnc localhost -port 4560

(Well, not simpler, but I think the output is clearer.)

3 Likes

I’m definitely out of my comfort zone with this stuff, but just wanted to confirm you followed all the instructions to complete the handshake first. Connect to ws://127.0.0.1:4560, then send the following:

{
    "message": "connect",
    "clientName": "Example Client Name",
    "handshakeVersion": "1.0"
}

After that, I get a message in Dorico:

After accepting that, Dorico sends the sessiontoken back. You need to respond with this, filling in the sessiontoken that Dorico sent you:

{
    "message": "acceptsessiontoken",
    "sessionToken": "12345678-aaaa-bbbb-cccc-1234567890ab"
}

After completing the handshake, it seems to work for me. I messed around with this a year or so ago, and never could figure out how to do the handshake with a Stream Deck. The Notation Express guys wrote a plugin to do it.

1 Like

That’s where it fails according to the OP. Without a connection, nothing can be sent or received.

1 Like

(This is all abstracted away in the C# library, so those JSON bits aren’t visible.)

1 Like

I checked that something is listening on 4560:
image
Then checked with PS:


which has me a bit confused as it seems to fail and succeed at the same time!

2 different protocols: ipv6 (fails) and ipv4 (succeeds). You can tell by the format of the IP address ::1 = ipv6, 127.0.0.1 = ipv4.

1 Like

… and this is not unusual. As you saw, I got the same results on my machine, but I’m able to connect to Dorico with the C# library.

Can you post your code here? Also, have you tried compiling and running Program.cs example from the library?

What confuses me is that you are getting System.Net.WebSockets.WebSocketException and System.Net.Http.HttpRequestException.

ConnectAsync method from the library already catches those and throws internal DoricoException which wraps the original exception as InnerException. So why are you not getting a DoricoException with Could not connect to Dorico. Make sure Dorico is running. message?

1 Like

Are you using the code from the sample project in the GitHub repo? If so, where are you getting the connection error? I have to switch to Dorico to allow the connection after line 36, and then I’m able to send other commands.

I am running the DoricoNetExample code in Program.cs in Visual Studio Code IDE. I’ve not yet created my own code to call the Dorico.Net.dll as wanted to investigate how it worked.

In the snippet that ikos posted, my error occurs on line 102


As I know that Dorico is running and that it is listening on the correct port (see previous posts), I wanted to know what the actual message was and this is shown in the Debug console of VSC

I’ve forked Scott’s original code into my own Github repo and I am connecting VSC to that.

If you set the log level to Debug on line 16 in Program.cs, you should get the sent and received message at the comms level.

If you set the log level to Trace you should get the messages at the WebSocket level, although there’s a bug in the current NuGet package where the wrong value is sent to the logger. I just pushed a change to GitHub to fix that. Not sure when I’ll publish a new NuGet at this moment.

1 Like

When I set the LogLevel to Trace the debug window shows the following:


I’m not sure that this sheds anymore light on the matter. In fact, I get the same messages whether Dorico is running or not!

I suspect the connection is closed directly and not the result of a message.

Do you have the full stack trace from the exception? What you posted earlier doesn’t show the Dorico.net part of the code path. That might help yield some ideas. Although I suspect this is environmental.

   ------------------------------------------------------------------------------
You may only use the Microsoft Visual Studio .NET/C/C++ Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software to help you
develop and test your applications.
------------------------------------------------------------------------------
trce: DoricoRemote[1150959493]
      Opening WebSocket: ws://127.0.0.1:4560/
trce: DoricoRemote[898765132]
      WebSocket opened: ws://127.0.0.1:4560/
Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Private.CoreLib.dll
Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Private.CoreLib.dll
Exception thrown: 'DoricoNet.Exceptions.DoricoException' in Dorico.Net.dll
Exception thrown: 'DoricoNet.Exceptions.DoricoException' in System.Private.CoreLib.dll
Unhandled exception. DoricoNet.Exceptions.DoricoException: Could not connect to Dorico. Make sure Dorico is running.
 ---> System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server
 ---> System.Net.Http.HttpRequestException: Connection refused (127.0.0.1:4560)
 ---> System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|285_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken)
   at DoricoNet.Comms.DoricoCommsContext.ConnectAsync(IConnectionArguments connectionArgs) in /workspaces/Dorico.Net/Dorico.Net/Comms/DoricoCommsContext.cs:line 119
   at DoricoNet.DoricoRemote.ConnectAsync(String clientName, IConnectionArguments connectionArguments) in /workspaces/Dorico.Net/Dorico.Net/DoricoRemote.cs:line 74
   --- End of inner exception stack trace ---
   at DoricoNet.DoricoRemote.ConnectAsync(String clientName, IConnectionArguments connectionArguments) in /workspaces/Dorico.Net/Dorico.Net/DoricoRemote.cs:line 102
   at Program.<Main>$(String[] args) in /workspaces/Dorico.Net/DoricoNetExample/Program.cs:line 36
   at Program.<Main>(String[] args)
The program '[49426] DoricoNetExample' has exited with code 0 (0x0).