RFC server with .Net connector Gateway not matching - c#

I'm working on a really simple app running as RFC Server. I installed SAP Netweaver 7.5 trial version. Here is the code to start the server :
private void button2_Click(object sender, EventArgs e)
{
RfcDestinationManager.RegisterDestinationConfiguration(new RfcDestinationConfig());
RfcServerManager.RegisterServerConfiguration(new RfcServerConfig());
Type[] handlers = new Type[1] { typeof(StfcConnectionStaticImpl) };
RfcServer server = RfcServerManager.GetServer("PRD_REG_SERVER", handlers);
server.Start();
}
Then the handling class :
class StfcConnectionStaticImpl
{
// The annotation binds the function (name) to its implementation
[RfcServerFunction(Name = "STFC_CONNECTION")]
public static void StfcConnection(RfcServerContext serverContext, IRfcFunction function)
{
Console.WriteLine("System Attributes: " + serverContext.SystemAttributes.ToString());
function.SetValue("ECHOTEXT", function.GetString("REQUTEXT"));
function.SetValue("RESPTEXT", "NCO3: Hello world.");
}
}
next the Rfc destination config class :
public class RfcDestinationConfig : IDestinationConfiguration
{
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
public bool ChangeEventsSupported()
{
return false;
}
public RfcConfigParameters GetParameters(string destinationName)
{
if ("PRD_000".Equals(destinationName))
{
RfcConfigParameters parms = new RfcConfigParameters();
parms.Add(RfcConfigParameters.AppServerHost, "172.18.3.22");
parms.Add(RfcConfigParameters.SystemNumber, "00");
parms.Add(RfcConfigParameters.User, "developer");
parms.Add(RfcConfigParameters.Password, "Appl1ance");
parms.Add(RfcConfigParameters.Client, "001");
parms.Add(RfcConfigParameters.Language, "EN");
parms.Add(RfcConfigParameters.PoolSize, "5");
parms.Add(RfcConfigParameters.MaxPoolSize, "10");
parms.Add(RfcConfigParameters.IdleTimeout, "600");
return parms;
}
else return null;
}
}
and last the Rfc server class :
public class RfcServerConfig : IServerConfiguration
{
public event RfcServerManager.ConfigurationChangeHandler ConfigurationChanged;
public bool ChangeEventsSupported()
{
return false;
}
public RfcConfigParameters GetParameters(string serverName)
{
if ("PRD_REG_SERVER".Equals(serverName))
{
RfcConfigParameters parms = new RfcConfigParameters();
parms.Add(RfcConfigParameters.GatewayHost, "172.18.3.22");
parms.Add(RfcConfigParameters.GatewayService, "sapgw00");
parms.Add(RfcConfigParameters.ProgramID, "DOT_NET_SERVER");
parms.Add(RfcConfigParameters.RepositoryDestination, "PRD_000");
parms.Add(RfcConfigParameters.RegistrationCount, "5");
return parms;
}
else return null;
}
}
The server start perfectly and my registration in the Gateway is ok.
SAP GATEWAY (SMGW)
The problem coming from Logged-on Client because I only see the external client and not the registered program :
Logged-on Client
My question is why I don't get the Program as Registered Server ?
Is there some SAP configuration to do to allow Program registration ?
If someone can't help me to solve this out, it will be great.
Thank you,
Ronan

Related

Receiving BLE advertisement packets on Windows published by iOS device

I'm attempting to communicate between windows and iOS using Bluetooth.
On the iOS side I'm publishing advertisements and on the windows side I'm "watching" for advertisements.
currently upon receiving the advertisements that my iOS device is publishing, these advertisements are... empty. No services, no ManufacturerData, DataSections list contains 1 DataSection with the Data of length 1 (?) local name is null, there's basically nothing in this advertisement packet of any use.
When I call BluetoothLEDevice.FromBluetoothAddressAsync(bluetooth address) I get an object, but with everything empty, no services, an element not found exception when I call GetGattService, DeviceInformation is null... nothing useful as far as I can see.
I don't know if there's something wrong with the advertisement I'm publishing on the iOS side, or if it's how I'm treating it on the Windows side.
Here is the iOS code:
import Foundation
import CoreBluetooth
class BluetoothController : NSObject, CBPeripheralManagerDelegate {
var delegate : BluetoothControllerDelegate?
var manager : CBPeripheralManager?
init(_ delegate : BluetoothControllerDelegate) {
super.init()
manager = CBPeripheralManager(delegate: self, queue: nil)
self.delegate = delegate
self.delegate?.statusUpdate("init")
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager){
delegate?.statusUpdate("Perepheral did update state : \(peripheral.state)")
if(peripheral.state == CBManagerState.poweredOn){
addServices()
}
}
func addServices(){
let service = CBMutableService(type: CBUUID.init(string: "e1fa36b4-9700-414b-a4e0-382a3e249e56"), primary: true)
// service.
manager?.add(service)
}
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?){
delegate?.statusUpdate("Service was added : \(service.uuid)")
manager?.startAdvertising(getAdvertisementData(service))
}
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?){
delegate?.statusUpdate("peripheralManagerDidStartAdvertising : \(peripheral.isAdvertising) : \(error.debugDescription)")
}
private func getAdvertisementData(_ service : CBService) -> Dictionary<String, Any>{
var data : Dictionary<String, Any> = Dictionary<String, Any>()
data["CBAdvertisementDataLocalNameKey"] = "e1fa36b4-9700-414b-a4e0-382a3e249e56"
data["CBAdvertisementDataServiceUUIDsKey"] = [service.uuid]
return data
}
}
And here is the Windows C# code (a simple console app for the moment) :
class Program
{
static void Main(string[] args)
{
BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
watcher.ScanningMode = BluetoothLEScanningMode.Active;
watcher.Received += Watcher_Received;
DeviceWatcher devWatcher = DeviceInformation.CreateWatcher();
devWatcher.Added += DevWatcher_Added;
devWatcher.Updated += DevWatcher_Updated;
watcher.Start();
devWatcher.Start();
while (true)
{
}
}
private static void DevWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
{
Console.Write("\nUpdated\n");
}
private static void DevWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
// Console.Write("Added : "+args.Name+"\n");
}
static List<ulong> tried = new List<ulong>();
private static async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
if (tried.Contains(args.BluetoothAddress)) {
return;
}
tried.Add(args.BluetoothAddress);
Console.Write("Device found =================================================");
Console.Write("\nDataSections: " + args.Advertisement.DataSections[0].Data);
//BluetoothLEDevice device =
BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
try
{
Console.Write("\n GattServices: " + device.GetGattService(Guid.Parse("e1fa36b4-9700-414b-a4e0-382a3e249e56")).Uuid);
}catch(Exception e)
{
Console.Write(e.ToString());
}
if(device.DeviceInformation == null)
{
Console.Write("DeviceInformation null");
return;
}
if(device.DeviceInformation.Pairing == null)
{
Console.Write("Pairing null");
return;
}
var res = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
Console.Write("Pair complete (?) ========================================"+res.Status);
}
}
Sorry it's a bit messy...
Thank you in advance for your help, I'm also trying it in the other direction (Windows advertising and iOS watching) it's not going well either, here's another question I've posted on this subject if interested: Listening to and accepting a BLE Connect request in windows
The advertisements are passive so you should change the code from active to passive such as:
watcher.ScanningMode = BluetoothLEScanningMode.Passive;
public sealed partial class MainPage : Page
{
Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher advertisementWatcher;
public MainPage()
{
this.InitializeComponent();
advertisementWatcher = new Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher();
advertisementWatcher.ScanningMode = Windows.Devices.Bluetooth.Advertisement.BluetoothLEScanningMode.Passive;
advertisementWatcher.Received += AdvertisementWatcher_Received;
advertisementWatcher.Start();
}
private void AdvertisementWatcher_Received(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher sender, Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs args)
{
System.Diagnostics.Debug.WriteLine("Address: {0:X}", args.BluetoothAddress);
}
}
With just the .Received callback you should start seeing data coming such as:
Address: A45E60F3E896 Address: 4BF5661A4EF2 Address: 549F476B5F37 Address: 4CB6DF3019A9 Address: 4BF5661A4EF2 Address: 106070EB42B1

Connecting Silverlight client to SignalR server

I've been driving myself nuts trying to resolve this issue so really hoping someone has some insight.
I have a console application which runs/hosts my signalR server.
I have already successfully connected to it using a web(javascript) client and a windows forms client with no trouble at all.
BUT for the life of me I cannot get a silverlight client to connect to it. Initially I was getting a
'System.Security.SecurityException' occurred in Microsoft.Threading.Tasks error
on
await Connection.Start();
I managed to fix that by force sending the clientaccesspolicy file using code i found on a random thread.
THREAD
However the connection still never establishes. The status goes thru connecting, disconnected, connection closed.
I am at my wits end as to why this won't work. Any input is appreciated. Code below.
MainPage.xaml.cs
public partial class MainPage : UserControl
{
private SignalRClient client;
public MainPage()
{
InitializeComponent();
dataGrid1.ItemsSource = new ItemsCollection();
client = new SignalRClient();
client.RunAsync();
Debug.WriteLine("Init Done");
}
}
-
SignalRClient.cs
public class SignalRClient
{
private HubConnection Connection { get; set; }
private IHubProxy HubProxy { get; set; }
const string url = "http://localhost:8080/";
public SignalRClient()
{
}
public async void RunAsync()
{
Connection = new HubConnection(url, useDefaultUrl: true);
Connection.Closed += Connection_Closed;
Connection.StateChanged += ConnectionDidSomething;
HubProxy = Connection.CreateHubProxy("TickerHub");
HubProxy.On<string>("receiveAllData", data => Debug.WriteLine("RECDATA={0}", data));
try
{
await Connection.Start();
}
catch (HttpClientException e)
{
Debug.WriteLine("Unable to connect to server.1 {0}", e.Message);
return;
}
catch (HttpRequestException e)
{
Debug.WriteLine("Unable to connect to server.2 {0}", e.Message);
return;
}
}
-
Server
class Program
{
static void Main(string[] args)
{
string url = "http://localhost:8080/";
using (WebApp.Start(url))
{
Console.WriteLine("SignalR server running on {0}", url);
Console.ReadLine();
}
Console.ReadLine();
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
Console.WriteLine("Configuration");
//Tried this approach too
/*app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});*/
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml");
}
}
-
TickerHub.cs
public class TickerHub : Hub
{
public override Task OnConnected()
{
string connectionID = Context.ConnectionId;
Console.WriteLine("New Connection:" + connectionID);
InitNewClient(connectionID);
return base.OnConnected();
}
//send all data to newly connected client
public void InitNewClient(string connectionID)
{
}
//client requested all data
public void GetAllData()
{
Console.WriteLine("Get Data Triggered");
Clients.All.receiveAllData("TESTING123");
}
}
I figured it out! Hopefully this helps someone in the future.
Its quite simple. This is what you need to have in your startup class configuration method.
Below that is the code required to send the clientaccesspolicy.xml.
class Startup
{
public void Configuration(IAppBuilder app)
{
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml");
}
}
-
public class ClientAccessPolicyConnection : PersistentConnection
{
public override Task ProcessRequest(Microsoft.AspNet.SignalR.Hosting.HostContext context)
{
string[] urlArray = context.Request.Url.ToString().Split('/');
string path = urlArray[urlArray.Length - 1];
if (path.Equals("clientaccesspolicy.xml", StringComparison.InvariantCultureIgnoreCase))
{
//Convert policy to byteArray
var array = Encoding.UTF8.GetBytes(ClientAccessPolicy);
var segment = new ArraySegment<byte>(array);
//Write response
context.Response.ContentType = "text/xml";
context.Response.Write(segment);
//Return empty task to escape from SignalR's default Connection/Transport checks.
return EmptyTask;
}
return EmptyTask;
}
private static readonly Task EmptyTask = MakeTask<object>(null);
public static Task<T> MakeTask<T>(T value)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
public static readonly string ClientAccessPolicy =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<access-policy>"
+ "<cross-domain-access>"
+ "<policy>"
+ "<allow-from http-request-headers=\"*\">"
+ "<domain uri=\"*\"/>"
+ "</allow-from>"
+ "<grant-to>"
+ "<resource path=\"/\" include-subpaths=\"true\"/>"
+ "</grant-to>"
+ "</policy>"
+ "</cross-domain-access>"
+ "</access-policy>";
}

SignalR connection to old browser drops if new browser opens

I have application in which I am showing data from sensors using SignalR. It uses ASP.net membership to authenticate the users. It all works fine if I only open one browser window(e.g. Firefox). If I open same website in another browser e.g. Chrome at the same time then signalR connection to firefox browser drops even if the user is different. This is what I am using to broadcast message:
Hub
[Authorize]
public class DataHub:Hub
{
private readonly RealTimeData _sensor;
public DataHub() : this(RealTimeData.Instance) { }
public DataHub(RealTimeData data)
{
_sensor = data;
}
public override Task OnConnected()
{
// _sensor.UserId = Context.ConnectionId; changed to
_sensor.UserId = Membership.GetUser().ProviderUserKey.ToString();
return base.OnConnected();
}
}
public class RealTimeData
{
//User Id
public String UserId { get; set; }
private readonly static Lazy<RealTimeData> _instance = new Lazy<RealTimeData>(() => new RealTimeData(GlobalHost.ConnectionManager.GetHubContext<DataHub>().Clients));// Singleton instance
private IHubConnectionContext Clients;
private void BroadcastDataOfAllSensors(List<SensorDetails> sensor)
{
//Clients.Client(UserId).updateDashboard(sensor);changed to
Clients.User(UserId).updateDashboard(sensor);
}
}
Application Startup
public class StartUp
{
public void Configuration(IAppBuilder app)
{
var idProvider = new UserIdProvider();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);
app.MapSignalR();
}
}
UserId
public class UserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
var userId = Membership.GetUser().ProviderUserKey;
return userId.ToString();
}
}

SignalR + passing custom object from server to client not working

I am trying to pass a custom object from self hosted signalr hub server to all the clients, the method in client side not getting invoked .But if the same custom class object is passed from client to server works fine, meaning it invokes the server method.
below is the sample code :
public class ChatHub : Hub
{
public void Send(DataContract message)
{
//below call not reaching to client while passing custom obj
Clients.All.SendMessage(message);
//below string passing works - means invokes client method
Clients.All.SendMsg("test");
}
}
custom class defined in both client and server project via dll:
public class DataContract
{
public string Name
{
get;set;
}
public int Id
{
get;set;
}
}
client side method:
public class SignalRClient
{
HubConnection hubConnection = null;
IHubProxy chat;
public SignalRClient()
{
hubConnection = new HubConnection("https://localhost/");
chat = hubConnection.CreateHubProxy("ChatHub");
}
public void StartConnection()
{
if (hubConnection != null)
{
hubConnection.Start().Wait();
}
chat.On<DataContract>("SendMessage", (stock) =>
{
Console.WriteLine("name {0} id {1}", stock.Name, stock.Id.ToString());
});
chat.On<string>("SendMsg", (message) =>
{
Console.WriteLine(message);
});
}
public void SendMessage(DataContract dd)
{
dd.Name = "test";
chat.Invoke("Send", dd).Wait();
}
public void SendMessage(string msg)
{
chat.Invoke("SendMsg", "Console app", msg).Wait();
}
}
//program.cs
main()
{
SignalRClient client = new SignalRClient();
client.StartConnection();
string msg = null;
while ((msg = Console.ReadLine()) != null)
{
DataContract dd = new DataContract { Name = "arun", Id = 9 };
//below calls reaches to server both string type and custome obj
client.SendMessage(dd);
client.SendMessage("client");
}
}
Any clue on why when calling from server (i.e Clients.All.SendMessage(message); ) not invoking client method when param is custom object.
Thanks in advance.

SignalR: I cannot call .net client method from server

I would like to implement a pub/sub application with .NET clients, so I'm testing SignalR by means of this minimal code.
This is the server:
namespace Test.SignalRComm.SimpleServer
{
using System.Threading.Tasks;
using log4net;
using SignalR;
using SignalR.Hosting.Self;
using SignalR.Hubs;
using SignalR.Infrastructure;
class Program
{
private static SignalRServer signalRServer = null;
static void Main(string[] args)
{
signalRServer = new SignalRServer();
signalRServer.Start();
System.Console.WriteLine("Press Enter to close...");
System.Console.ReadLine();
signalRServer.Stop();
}
}
public class SignalRServer
{
private string serverUrl = null;
public Server signalRServer = null;
public SignalRServer()
{
serverUrl = #"http://localhost:5001/";
signalRServer = new SignalR.Hosting.Self.Server(serverUrl);
signalRServer.EnableHubs();
}
public void Start()
{
signalRServer.Start();
}
public void Stop()
{
IConnectionManager connManager = signalRServer.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connManager.GetClients<SignalRTestHub>();
clients.AddMessage("Test");
signalRServer.Stop();
}
}
public class SignalRTestHub : Hub, IDisconnect
{
private static readonly ILog logger = LogManager.GetLogger(typeof(SignalRTestHub));
public void Register(string token)
{
AddToGroup(token).ContinueWith(task =>
{
if (task.IsFaulted)
logger.Error(task.Exception.GetBaseException());
else
{
string message = string.Format("Client {0} registered with token <{1}>", Context.ConnectionId, token);
logger.Info(message);
}
});
}
public void Unregister(string token)
{
RemoveFromGroup(token).ContinueWith(task =>
{
if (task.IsFaulted)
logger.Error(task.Exception.GetBaseException());
else
logger.InfoFormat("Client {0} unregistered from token <{1}>", Context.ConnectionId, token);
});
}
public Task Disconnect()
{
string message = string.Format("Client {0} disconnected", Context.ConnectionId);
logger.Info(message);
return null;
}
}
}
and this is the client:
namespace Test.SignalRComm.SimpleClient
{
using System.Threading.Tasks;
using log4net;
using SignalR.Client.Hubs;
class Program
{
private static readonly ILog logger = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
SignalRClient client = new SignalRClient("http://localhost:5001/");
client.Start().ContinueWith(task =>
{
if (task.IsFaulted)
{
logger.Error("Failed to start!", task.Exception.GetBaseException());
}
else
{
logger.InfoFormat("Success! Connected with client connection id {0}", client.ConnectionId);
// Do more stuff here
client.Invoke("Register", "Test").ContinueWith(tsk =>
{
if (tsk.IsFaulted)
logger.Error("Failed to start!", tsk.Exception.GetBaseException());
else
logger.Info("Success! Registered!");
});
}
});
System.Console.WriteLine("Press Enter to close...");
System.Console.ReadLine();
client.Invoke("Unregister", "Test").ContinueWith(tsk =>
{
if (tsk.IsFaulted)
logger.Error("Failed to stop!", tsk.Exception.GetBaseException());
else
logger.InfoFormat("Success! Unregistered!");
});
client.Stop();
}
}
public class SignalRClient : HubConnection
{
private static readonly ILog logger = LogManager.GetLogger(typeof(SignalRClient));
IHubProxy hub = null;
public SignalRClient(string url)
: base(url)
{
hub = CreateProxy("Test.SignalRComm.SimpleServer.SignalRTestHub");
}
public Task Invoke(string methodName, params object[] args)
{
return hub.Invoke(methodName, args);
}
public void AddMessage(string data)
{
logger.InfoFormat("Received {0}!", data);
}
}
}
While invoking hub methods from client (Register and Unregister) works fine, I'm not able to call client AddMessage method from hub.
Furthermore the Disconnect method of the hub is never called when a client is closed.
What I'm doing wrong? I'm not able to find any working example.
Edit
Subscribing to hubs events on the client like this:
hub.On<string>("Notify", message => Console.Writeline("Server sent message {0}", message);
and triggering the event on the hub like this:
Clients.Notify("Something to notify");
makes the notifications from server to clients working.
I'm still unable to detect a client disconnection. I implemented the IDisconnect interface on the hub, but when a client connection stops, the Disconnect method on the hub isn't triggered.
Thanks for your help.
Take a look at how to use the .NET client here:
https://gist.github.com/1324342
And API docs here:
https://github.com/SignalR/SignalR/wiki
TL;DR you need to subscribe to specific methods, deriving from the hubConnection doesn't make any magic happen.

Categories