BSP Application: Clients IP Address - abap

Is it possible to read the clients ip address in an SAP BSP Application? We'd like to save the ip for a later moment.
The connection comes via a WebDispatcher in our DMZ to the SAP WAS.
Thanks,
h.

Here's a quick example how to do this; create a controller and implement the DO_REQUEST like this:
method do_request.
data remote_ip type string.
remote_ip = request->get_header_field( `~remote_addr` ).
write( remote_ip ).
endmethod.
Edit: I could not test this with a web dispatcher though.

Ordinarily, that should be possible, but since you're behind a Web Dispatcher, I'd say you'll only ever see the IP of the Web Dispatcher. You'll probably have to implement some kind of logging there instead of inside the BSP application.

Related

How to reference the WCF service by code-behind in UWP?

Now I need to reference a WCF service in a UWP program. However, the address of the WCF service may change frequently in the future.
I don't want to rebuild/republish the project every time when the address change.
So I want to use a LocalSettings to Save/Load the address of WCF service. Every the program begins, it will reload the address from the LocalSettings. And if the address changes, I just only let the customer change the LocalSettings from UI but not need to rebuild/republish the project.
How can I do it? Or there is any other better to do it?
If it's a RESTful service, you could use HttpClient relevant APIs to consume a REST service in UWP.
Please note that REST is a resource that implements a uniform interface using standard HTTP GET, POST, PUT methods that can be located by URI. So, you could use HttpClient to call it in code-behind. You will get response after you send http request, then you could analysis the response result.
The similar thread for your reference: Calling web service asynchronously in page constructor.
Using LocalSettings for such thing is a good solution.
LocalSettings are just a dictionary where you can assign values you want to store and later take out.
ApplicationData.Current.LocalSettings["ServiceAddress"] = "something";
Debug.WriteLine(ApplicationData.Current.LocalSettings["ServiceAddress"]);
Such setting will survive app restart and is stored in applicaton's private storage.
You will probably want to seed this setting with a default value at first startup.

single WCF endpoint for all commands in Nservicebus

We are trying to build a Nservicebus service that can communicated with form and wpf based clients using WCF. I have read that you can inherit from WcfService.
like:
public class ThirdPartyWebSvc : WcfService<ThirdPartyCmd, ThirdPartyCmdResponse>
And then you simple create a endpoint in the app.config and you done like described here. but the problem is that i have to create a endpoint for every command.
I would like to have a single endpoint that excepts any command and returns its response.
public class ThirdPartyWebSvc : WcfService<ICommand, IMessage>
Can someone point me in the right direction? Using Nservicebus for client communication can't be done for us and i don't want to build a proxy like server unless thats the only way to do it.
Thanks
So from what I can gather, you want to expose a WCF service operation which consumers can call to polymorphically pass one of a number of possible commands to, and then have the service route that command to the correct NServiceBus endpoint which then handles the command.
Firstly, in order to achieve this you should forget about using the NserviceBus.WcfService base class, because to use this you must closely follow the guidance in the article you linked in your post.
Instead, you could:
design your service operation contract to accept polymorphic requests by using the ServiceKnownType attribute on your operation definition, adding all possible command types,
host the service using a regular System.ServiceModel.ServiceHost(), and then configure an NserviceBus.IBus in the startup of your hosted WCF service, and
define your UnicastBusConfig config section in your service config file by adding all the command types along with the recipient queue addresses
However, you now have the following drawbacks:
Because of the requirement to be able to pass in implementations of ICommand into the service, you will need to recompile your operation contract each time you need to add a new command type.
You will need to manage a large quantity of routing information in the config file, and if any of the recipient endpoints change, you will need to change your service config.
If your service has availability problems then no more messages to any of your NSB endpoints.
You will need to write code to handle what to do if you do not receive a response message from the NSB endpoints in a timely manner, and this logic may depend on the type of command sent.
I hope you are beginning to see how centralizing this functionality is not a great idea.
All the above problems would go away if you could get your clients to send commands to the bus in the standard way, but without msmq how can you do that?
Well, for a start you could look at using one of the other supported transports.
If none of these work for you and you have to use WCF hosted services, then you must follow the guidance in the linked article. This guidance is there to steer you in the correct direction - multiple WCF services sounds like a pain, until you try to centralize them into a single service - then the pain gets bigger, not less.

Domain Model for Remote devices

I'm looking for design advice for a domain model scenario I have.
Let's say I have have a squad of Robots, each controllable via a wireless network connection.
I have an IRobot domain object that represents a real-world robot. The interface looks like so:
public interface IRobot
{
void MoveHeadUp(int toAngle);
void MoveHeadDown(int toAngle);
int GetHeadAngle();
}
Example scenario: A virtual robot is shown in a GUI. In offline mode, the GUI shows what would happen if we tell the domain object (IRobot) to raise its head 5 degrees.
In online mode, the GUI would show the robot move AND the command would be sent to the physical robot and it would move as well.
I'm trying to add remote capabilities around this domain object, ie. getting/setting remote state via Ethernet or serial, etc. I don't want to pollute the domain object with network connectivity issues.
What is the best approach to implement IRobot domain behaviour and keep remote connection implementation details separate?
My take on this is messaging.
All of your commands (and that's what you're giving your robots), could be efficiently communicated over whatever you need (transport of your choice) and your robot (virtual or physical) would receive the command and act on it.
You can think of these robots as endpoints. Each endpoint has a name/address. You're dispatching a command to those robots and it's no longer your concern how on the robot (physical or emulated) command is executed.
You have mentioned
In online mode
Does that mean you also have an offline mode? If so, I'd look into messaging for sure.

Detect when client connected to wcf service

From a little bit of reading around, it is my understanding that the only way to detect that a client has connected to my service is through writing my own code. I am using a Singleton service. I would like to display a message every time a client connects to my service that client x with ip xxx has connected. There is no built-in event that is generated? Am I correct?
No, I don't think there's any support in WCF for your requirement.
Not sure what you want to achieve with this, either. Your service class (in your case, just a single instance) really doesn't have any business putting up messages (on screen, I presume) - that really not it's job. The service class is used to handle a request and deliver a response - nothing more.
The ServiceHost class might be more of a candidate for this feature - but again, it's job really is to host the service, spin up the WCF runtime etc. - and it's really not a UI component, either.
What you could possibly do is this
have an Admin UI (a Winforms, console, or WPF app) running on your server alongside your service, providing an admin service to call
define a fast connection between the two services (using e.g. netNamedPipe binding which is perfect for intra-application messaging)
when your "real" service gets a call, the first thing it does is send out a message to the admin UI which can then pick up that message and handle it
That way, you could cleanly separate your real service and it's job (to provide that service) and the Admin UI stuff you want to do and build a cleanly separated system.
I have actually implemented my own connect, disconnect and ping service methods which I manually call from my client once the channel has been created. By using them as a kind of header section in all of my ServiceContract interface definitions (and their implementations, of course), they form an makeshift "base service definition" that only requires a bit of cut-n-paste.
The string-based parameters of connect and disconnect will be used to send client info to the server and return server info and (perhaps a unique connection id) to the client. In addition a set of timing reference points may make its way in also.
Note how SessionMode is required and the individual OperationContract properties IsInitiating and IsTerminating are explicitly specified for each method, the end result being what I would call a "single-session" service in that it defines connect and disconnect as the sole session bookends.
Note also that the ping command will be used as the target of a timer-based "heartbeat" call that tests the service connection state and defeats ALL connection timeouts without a single config file :-)
Note also that I haven't determined my fault-handling structure yet which may very well add a method or more and/or require other kinds of changes.
[ServiceContract( SessionMode = SessionMode.Required )]
public interface IRePropDalSvr {
[OperationContract( IsInitiating=true, IsTerminating=false )]
string connect (string pClientInfo);
[OperationContract( IsInitiating=false, IsTerminating=true, IsOneWay=true )]
void disconnect (string pClientInfo);
// ------------------------------------------------------------------------------------------
[OperationContract( IsInitiating=false, IsTerminating=false )]
string ping (string pInp);
// ------------------------------------------------------------------------------------------
// REST OF ServiceContract DEFINITION GOES HERE
One caveat: while I am currently using this code and its implemention in my service classes, I have not verified the code yet.

WCF Named Pipe IPC

I have been trying to get up to speed on Named Pipes this week. The task I am trying to solve with them is that I have an existing windows service that is acting as a device driver that funnels data from an external device into a database. Now I have to modify this service and add an optional user front end (on the same machine, using a form of IPC) that can monitor the data as it passes between the device and the DB as well as send some commands back to the service.
My initial ideas for the IPC were either named pipes or memory mapped files. So far I have been working through the named pipe idea using WCF Tutorial Basic Interprocess Communication . My idea is to set the Windows service up with an additional thread that implements the WCF NamedPipe Service and use that as a conduit to the internals of my driver.
I have the sample code working, however I can not get my head around 2 issues that I am hoping that someone here can help me with:
In the tutorial the ServiceHost is instantiated with a typeof(StringReverser) rather than by referencing a concrete class. Thus there seems to be no mechanism for the Server to interact with the service itself (between the host.Open() and host.Close() lines). Is it possible to create a link between and pass information between the server and the class that actually implements the service? If so, how?
If I run a single instance of the server and then run multiple instance of the clients, it seems that each client gets a separate instance of the service class. I tried adding some state information to the class implementing the service and it was only retained within the instance of the named pipe. This is possibly related to the first question, but is there anyway to force the named pipes to use the same instance of the class that is implementing the service?
Finally, any thoughts on MMF vs Named Pipes?
Edit - About the solution
As per Tomasr's answer the solution lies in using the correct constructor in order to supply a concrete singleton class that implements the service (ServiceHost Constructor (Object, Uri[])). What I did not appreciate at the time was his reference to ensuring the service class was thread safe. Naively just changing the constructor caused a crash in the server, and that ultimately lead me down the path of understanding InstanceContextMode from this blog entry Instancecontextmode And Concurrencymode. Setting the correct context nicely finished off the solution.
For (1) and (2) the answer is simple: You can ask WCF to use a singleton instance of your service to handle all requests. Mostly all you need to do is use the alternate ServiceHost constructor that takes an Object instance instead of a type.
Notice, however, that you'll be responsible for making your service class thread safe.
As for 3, it really depends a lot on what you need to do, your performance needs, how many clients you expect at the same time, the amount of data you'll be moving and for how long it needs to be available, etc.