I am looking for some guidance on setting up an MVC/XSockets project on our servers running Windows Server 2003, R2 with IIS6.
Our team is developing a webapp that uses XSockets 3.x to dynamically display data in real time. We are using our time entry system to show current time entries on a "dashboard." Employees enter their times via a separate app, and the dashboard app is supposed to show most recent activity updates.
The project is made using the MVC4 framework. This works great when testing from my development machine, separate from the server. The ws server instance is setup on ws://x.x.x.x:4502, where x.x.x.x is the server's IP. The XSockets components are integrated in the same project.
After pushing my local project onto the server and doing some setup, everything works okay except the XSockets functionality. The XSockets server cannot be accessed from outside the server. When I test from within the server, meaning opening up a browser and going to the webapp, it works fine as it does on my dev machine.
I have tried following the custom configuration setup outlined on xsockets.net, but I am a little confused as to how to define the ws server instance. Do I use the server's IP? The localhost IP (127.0.0.1)? I tried both, but it won't work. I tried adding this custom config settings:
public class XSocketsConfig : ConfigurationSetting
{
public XSocketsConfig() : base(new Uri("ws://dashboard.ourdomain.com:4502/"), new Uri("ws://x.x.x.x:4502")) { }
}
From javascript I access the XSocket through the "ws://dashboard.ourdomain.com:4502/" connection, but it didn't work when I tested it after deploying to the server. I also tried:
public class XSocketsConfig : ConfigurationSetting
{
public XSocketsConfig() : base(new Uri("ws://x.x.x.x:4502")) { }
}
or
public class XSocketsConfig : ConfigurationSetting
{
public XSocketsConfig() : base(new Uri("ws://127.0.0.1:4502")) { }
}
I did enable the server firewall to let traffic through port 4502. Again, everything works great on my local machine, so this leaves me to believe it is either a setting on the server, or a config setting for XSockets.
What is the proper way of achieving a client-server connection on IIS 6? Pointers and suggestions are greatly appreciated as my several-day search has yielded no effective results yet.
Okay so I have finally figured it out. It was after all a firewall issue. I had to configure the firewall to allow traffic on the public ip and port and to forward that traffic to the private ip and port. My XSockets configuration ended up looking like this:
//http://xsockets.net/docs/configuration#public--private-endpoint
public class XSocketsConfig : ConfigurationSetting
{
public XSocketsConfig() : base(new Uri("ws://x.x.x.x:4502/"), new Uri("ws://y.y.y.y:4502")) { }
}
Where x.x.x.x is the server's public IP address and y.y.y.y the private IP address on the LAN. On the client side (js) I then do:
var conn = new XSockets.WebSocket('ws://x.x.x.x:4502/Activity');
That took a serious amount of troubleshooting but I am glad I got it figured out.
Related
I'm having a ton of problems getting an ASP.NET Core 2.1 web application up and running. I need it to run under http.sys (WebListener) on a shared port (80 or 443). I'd also like it to automatically redirect from http (80) to https (443). Of course, I don't want to hard code the listener addresses for http.sys - I need to pull those from a configuration file, but they're hard coded for now. I reserved the appropriate URLs with netsh, but when I run the app I get a warning:
warn: Microsoft.AspNetCore.Server.HttpSys.MessagePump[0]
Overriding address(es) 'http://sharedhost.vbcoa.com:80/app/, https://sharedhost.vbcoa.com:443/app/'. Binding to endpoints added to UrlPrefixes instead.
The app starts, but I can't browse to it with Microsoft Edge at all. Any other web browser is fine - as long as I disable HTTPS. For some reason, the application is forwarding to port 5001, instead of 443.
I figured all of this out. There are four problems. I'll address them each individually.
When configuring http.sys, a warning is issued about overriding local URLs
The UseHttpSys extension method of IWebHostBuilder accepts an options argument with a UrlPrefixes property. However, this is not where you should configure URLs - even if you're using http.sys. You can hardcode them with the UseUrls extension method of IWebHostBuilder, but it would be better to pull it from configuration, which leads to the second problem:
Configuration should be read from appsettings.json
To specify which URLs you want to run the application on, add them to the "urls" element in appsettings.json, as follows:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"urls": "http://sharedhost.vbcoa.com:80/app/;https://sharedhost.vbcoa.com:443/app/"
}
Then you'll need to create a ConfigurationBuilder object, add the appsettings.json file to it, build the configuration (with the Build method) and tell IWebHostBuilder to use that configuration, with the UseConfiguration extension method:
public static void Main(string[] args)
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var hostBuilder = WebHost.CreateDefaultBuilder(args)
.UseConfiguration(configBuilder.Build())
.UseHttpSys()
.UseStartup<Startup>();
hostBuilder.Build().Run();
}
Redirection goes to port 5001, not 443
HTTPS redirection is specified in the Configure method of Startup - that functionality comes out of the box. However, by default it will forward to port 5001, even if you have another port specified in your bound URLs from above. To override it, you need to inject HTTPS redirection options via a service. That's handled in the ConfigureServices method of Startup. Add the following line to that method:
services.AddHttpsRedirection(options => { options.HttpsPort = 443; });
Microsoft Edge won't show the web app, even though every other browser will
This is a problem with localhost loopback isolation in Windows Store apps. It seems to affect Windows 10 Enterprise, as discussed here: Microsoft Edge is not able to recognize localhost. To correct it, you need to do two things:
Make sure "Allow localhost loopback" is checked in Edge's "about:flags" page.
Launch a Command Prompt or Powershell Prompt as an Administrator and enter the following:
CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe
That should do it!
I have two servers, the servers are the same windows version.
When I do this call
https://10.197.68.32/portaleclientiapi/odata/v1/ticket('FINLU%235R000239')?$expand=attachments&$select=attachments
the reply is this
{
"#odata.context":"https://10.197.68.32/mpssapi/odata/v1/$metadata#ticket(attachments)/$entity","attachments":[
]
}
but when I call the second server the answer is this
{
"#odata.context":"https://10.197.68.33/portaleclientiapi/odata/v1/$metadata#ticket(attachments)/$entity"
}
the call is exactly the same, but change only the ip address
10.197.68.32 or 10.197.68.33
can someone tell me where is the problem?
Both server have the same published website, I tried to copy files from the running ok server to the running bad server
Thanks
put [EnableQuery] on the action or put [AutoExpand] on the property Attachment in the model
I'm doing my dev work on a Window 7 x64 machine, deploying to a Windows 2008 x32 server. At the moment I'm adding WCF services to some internal apps so that we can build smaller clients using net.tcp bindings that report to the user what the server is doing without running multiple instances of the server. To cut back on how much administration the apps will require, I tried enabling port sharing on my first server app. I'm using the app to self-host the WCF service so they can be easily moved from one server to another if necessary. Here's the code starting the server:
Dim _service_host As ServiceHost
Dim active_server_address As Uri = New UriBuilder("net.tcp", "localhost", CInt(My.Settings.ServerPort)).Uri
_service_host = New ServiceHost(GetType(UpdateServiceOps), active_server_address)
_service_host.AddServiceEndpoint(GetType(IUpdateService), New NetTcpBinding With {.Name = "endpoint_tcp"}, "MiddlewareEndpoint")
_service_host.Description.Behaviors.Add(New ServiceMetadataBehavior)
_service_host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
_service_host.Open()
That works great. When I change it to what's below, however, I get an error. Here's the code:
Dim _service_host As ServiceHost
Dim active_server_address As Uri = New UriBuilder("net.tcp", "localhost", CInt(My.Settings.ServerPort)).Uri
_service_host = New ServiceHost(GetType(UpdateServiceOps), active_server_address)
_service_host.AddServiceEndpoint(GetType(IUpdateService), New NetTcpBinding With {.Name = "endpoint_tcp", .PortSharingEnabled = True}, "MiddlewareEndpoint")
_service_host.Description.Behaviors.Add(New ServiceMetadataBehavior)
_service_host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
_service_host.Open()
I get the following error when I put a breakpoint at the last line: Unable to automatically step into the server. Connecting to the server machine 'nettcpportsharing' failed. The requested name is valid, but no data of the requested type was found. The Try...Catch block housing that code says the exception type is AddressAlreadyInUseException...but when I run netstat I don't see anything else listening on that address. There's no occurrence of 'nettcpportsharing' anywhere in my solution. I've checked to make sure that the Net.Tcp Port Sharing service is started. Any ideas?
I think this may be a permissions issue. Please see the associated article which explains how to configure the port sharing service to support self-hosted services.
(For production purposes I would strongly recommend using IIS Hosting with WAS anyway - it makes management of the services much cleaner and you get dynamic startup/shutdown for free.)
Right now I have my URLs hard-coded for HTTPService to work with my local machine's web server so that I don't need to copy files to htdocs after compiling. What's a good technique to easily transition HTTPService URLs from working on my testing setup to working with a normal web server setup?
Write a service to get the current environment your application is in, similar to how one tests if you're running in AIR or Flex.
In your HTTPService:
url="EnvironmentService.getURL1();"
In EnvironmentService:
public static function getUrl1():URL
{
return (LOCAL_ENVIRONMENT)? LOCAL_URL1 : LIVE_URL1;
}
If this doesn't work for you, post some more code and we'll work on a solution
Using Silverlight 3, Windows XP, IIS 5.1, I've written a small app which uses the channel method of calling the server rather than the 'add service reference' as per this MSFT article.
The application opens and the call to the server work when running it on the development computer in VS 2008 using the address localhost plus the port number. When I change the address to the computer name, dellnov2006, and publish the application to IIS, the application opens, but the call to the web service does not work.
Watching the call in Web Dev Helper, I see that the app was trying to call the service file, http://dellnov2006/Service1.svc, and is getting a 404 error.
So far, I've:
-In IIS mapped the .svc type to aspnet-isapi.dll
-Run the utility CleanIISScriptMaps
-Run aspnet_regiis.exe -i –enable
Any help would be appreciated - I am running out of ideas on this.
--
Here is the call back to the server, and the contents of the Service1.svc file:
private void Button_Click(object sender, RoutedEventArgs e)
{
// create a custom binding that uses HTTP and binary encoding
var elements = new List<BindingElement>();
elements.Add(new BinaryMessageEncodingBindingElement());
elements.Add(new HttpTransportBindingElement());
var binding = new CustomBinding(elements);
// create a channel factory for the service endpoint configured
// with custom binding
//var cf = new ChannelFactory<IService1>(binding,
// new EndpointAddress("http://localhost:1042/Service1.svc"));
var cf = new ChannelFactory<IService1>(binding,
new EndpointAddress("http://dellnov2006/Service1.svc"));
// save the syncronized context for the ui thread
uiThead = SynchronizationContext.Current;
// open the channel
IService1 channel = cf.CreateChannel();
// invoke the method asychrnoously
channel.BeginGetPerson(4, GetPersonCallback, channel);
}
Here are the contents of the svc file for what they are worth:
<%# ServiceHost Language="C#" Debug="true" Service="SilverlightChannelApp1.Web.Service1" CodeBehind="Service1.svc.cs" %>
Many thanks
Mike Thomas
Could be one of the following:
A problem with the web.config of the service. For example that localhost was part of the address.
That the service cannot find the dll which should be in the bin directory
Try browsing to the service with a web browser
Try adding the port number to the computer name. Whenever I'm testing local sites through a virtual machine that is always a necessity for me.
Change this:
new EndpointAddress("http://dellnov2006/Service1.svc"));
To this:
new EndpointAddress("http://dellnov2006:1042/Service1.svc"));
The solution to this was very simple, but it took both of your answers for me to think of
it.
Browsing to the service as suggested by Shiraz worked, so problem with calling service.
Suggestion to change endpoint address to include port # sounded good, but did not work.
Solution was to change:
new EndpointAddress("http://dellnov2006/Service1.svc"));
to this:
new EndpointAddress("http://dellnov2006/Silverlight/Service1.svc"));
where 'Silverlight' is the alias of the virtual directory. In other words, I open the app on IIS as 'http://dellnov2006/Silverlight/
Many thanks, I cannot believe how simple that was after so much time spent looking. I work alone and if it were not for this forum I'd be in serious trouble.
Mike Thomas