This has been discussed here but without a conclusion.
I would like to set up a WebSocket server in a self hosted Windows Service where I currently have multiple REST web services running on WCF. My requirements are not that advanced, I just need to consume an incoming stream of data. The problem is that I cannot change the way the data is send, if I could I would just convert it to a streamed HTTP POST, but this is not possible as the protocol is fixed.
According to Microsoft the WebSocket Class should be available from .NET Framework 4.5 and I am using .NET Framework 4.8 that is also supported but nowhere can I find how to self host it. There are many examples using IIS which I do not use.
So what I want to know is, 1) can the WebSocket class be used to self host a WebSocket Server inside a Windows Service?
If so how is it done? Looking for some example code.
EDIT
I think this might be somewhat undocumented but I finally got it to work. The magic seem to be replacing localhost or * with +. The following seem to work hosting the WebSocket while maintaining working WCF web services.
WebSocketsServer.Start("http://+:80/Socket/");
Some of it was described here but I could not make out when to use + or * and what their actual uses are.
When a port is specified, the host element can be replaced with "*" to
indicate that the HttpListener accepts requests sent to the port if
the requested URI does not match any other prefix. For example, to
receive all requests sent to port 8080 when the requested URI is not
handled by any HttpListener, the prefix is http://*:8080/. Similarly,
to specify that the HttpListener accepts all requests sent to a port,
replace the host element with the "+" character. For example,
https://+:8080. The "*" and "+" characters can be present in prefixes
that include paths.
I still do not think this makes sense fully. Anyone have a reference to why this would work?
Related
I am currently using NMS (C#), and I provide it with three server addresses with a priority server with the expectation for it to connect to the 2nd or 3rd server when the main is offline and then re-connect with the main server once back online.
The servers are third-party hosted whereas I'm developing the client.
I am using the following nugets:
Apache.NMS.ActiveMQ (1.8.0)
Apache.NMS (1.8.0)
Broker version 5.16.2 - 5.16.4
Connection string:
failover:(tcp://mainServer:61619,tcp://backup1:61619,tcp://backup2:61619)?randomize=false&timeout=10000&backup=true&priorityBackup=true&useExponentialBackOff=true&reconnectDelayExponent=2.0&initialReconnectDelay=5000&initialReconnectDelay=180000&consumerExpiryCheckEnabled=false
I'm providing it with randomize=false but yet it is still selecting a server a random and it does not seem to set the useExponentialBackOff either.
I have also tried nested.randomize=false
The NMS.ActiveMQ client is different than the Java client in that URI options require prefixes in order for the parser to figure out how to apply them. For the failover options the prefix is "transport." e.g "transport.randomize=false". This is documented on the website for the NMS.ActiveMQ client here.
To my recollection the NMS.ActiveMQ client doesn't support the priority backup options (and they aren't on the site) so that probably won't work as you are expecting it to.
I am currently working on an Owin self-hosted web service that runs on my machine and that allows peers (other machines) to download files from its virtual directory with microsoft's BITS. The downloads will work with relatively small files, but whenever I have to download large files (over 2Go) I get this error from BITS:
"The server does not support the necessary HTTP protocol. Background
Intelligent Transfer Service (BITS) requires that the server support
the Range protocol header."
I was wondering if there was a way to enable the Range Requests in Owin or if I have to implement manually the "data chunking" in the requests I receive. Because changing the content of every request to have the header "Accept-Ranges: bytes" doesn't seem to work (I assumed it would not magically worked, but I tried it anyway).
I couldn't find a lot of information on what I am trying to do besides finding out how to know if a server is supporting the range requests.
There was this question that seemed to look similar to mine, but was more focussed on setting the headers properly. It doesn't really show if/how the code splits the file before returning the response. There was also something about IIS, but my web service doesn't run on IIS, it runs on the client's machine and is instanciated by a windows service.
I found a solution to my problem. With a little bit more research on the subject, I discovered this article which sums up really well the problem I had, which is that requests going trough ASP.NET Http Handlers do not support Range-specific requests. So I will have to manually implement support for the range specific requests in my web service.
From my understanding, the beauty of signal R is that it takes care of the "handshake" between the client and server to determine the best form of communciation between them (websockets, long polling, etc). I understand that by default it does this at the /signalr route. I read that before this the handshake would be accomplished with an HTTP Get request with an Upgrade/Connection header specifying to upgrade to this new connection.
In my current application we support handling many HTTP requests in a RESTful manner. If we wanted to expose some of this data in real time rather than in this request response format, what would be the best way to determine if we should open a connection using signal R? Would checking for those headers still suffice? I just feel like that is a bit redundant since signal R abstracts that away.
Instead of this, would a solution be for the client to specifically invoke a hub method to kick off the streaming as soon as he connects to the proper endpoint?
TLDR: Need a way to open a signal R connection from a HTTP request, don't know the best way to go about that whether it be from requesting the resource with custom HTTP headers or by just navigating to the url resource and having their client invoke a hub method.
A typical example of using signalr is:
an html file using JavaScript to connect to a signalr Server when the page is loaded. we call this signalr client.
a signalr server written in c#. it can be a winform or console or service.
the signalr Server can call any dll, or webservices or webapi located in the same server, or even in different Server.
then, the client can call any function defined in the signalr server. the server can call any function defined in the client for a particular client or for groups of clients.
also, client x can call client y functions as well.
I would also suggest you create this index.html inside a Cordova project, so that your client can use this app using any pc desktop browser, or any mobile phone browser, or run it as an Android or iPhone native app, by using One set of client codes.
if they navigate to some url resource instead of receiving a response with json in its body we want them to be constantly in real time using signal r receiving data
I don't think this is possible with SignalR. Reason is that all SignaR communication is done through single route (xxx.xxx.xxx.xxx/signalR) + all SignaR connections are established using handshake (By client sending negotiate request to this route. Well maybe not all - not sure if negotiation is happening in case you initialize SignalR connection object with specific transport).
I've got a Web API that must communicate with a few different services. Currently, I have the Web API set to use the following security protocol:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
When the API calls out to another service via HttpClient (say like Twitter), it will use that protocol. At the same time however, another request may come in to access something from the cloud, which for whatever reason, currently requires TLS (not TLS 1.2). The request to the cloud, before firing out, sets the security protocol again:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
The problem I'm running into is when two separate and unique requests come in, one for Twitter and one for the cloud, the security protocol could switch over to the "wrong one" before it's sent out, causing the request to fail.
Is there a way to set the security protocol on the HttpClient per request so that I'm not swapping around a setting in some singleton somewhere?
You don't need to set it.
You can use:
using System.Net;
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
Additional Notes:
Needed for .Net 4.5 because Tls12 is not a default protocol.
Need to write the above code only once within the application. (For example within Global.asax > Application_Start within Web application or equivalent in Winforms application)
For .Net 4.6 and above, Tls12 is a default protocol so it is not needed
There seems to be no way to do this. The SecurityProtocol property is only being used inside the internal TlsStream class in one place:
TlsStream seems to back all the internal TLS connections such as HTTP, FTP and SMTP.
I had hoped that ServicePoint allows you to configure this. For many settings ServicePointManager only provides the default. That hope was unfounded.
So this is quite strong evidence that this is not possible. It's no proof, though.
What should you do? I'd switch out the HTTP client library for the odd server you are talking to. HTTP is not a particularly complicated protocol. I'm sure there's some other implementation available.
Alternatively, use a proxy that terminates the HTTPS connection on your own server. .NET then only deals with HTTP.
I want to integrate an API that will allow my application to send requests to a web server. Unfortunately, this API is not well documented, and I have not gotten a reply from the person who supports the web service that released the API. The instructions on how to integrate the API are the following:
All API calls connect to the standard SSL port, and must begin with
https://www.websitename.com/api.php?username=username&password=password&,
followed by the list of parameters expressed as parametername=value&
I am new to C# development. Can you interpret this set of instructions and tell me how I'd go about integrating this API? I mainly am confused about connecting to the SSL port.
This sounds like it's just an HTTP request to that particular URL. You want to use the WebClient class, and possibly call the DownloadString method, depending on what the response contains.
The standard SSL port is 443, but if you're using a library that parses URLs correctly, it will connect to that port automatically if it sees https:// at the beginning. You can use a custom port by providing it after the hostname (separated by a :), such as https://websitename.com:8443/, if you had an SSL service running on port 8443 instead of 443.