ASP.NET Core SignalR Client WSS Issue - asp.net-core-signalr

I have a console application (client) with package
Microsoft.AspNetCore.SignalR.Client installed. I'm trying to connect to wss and send request (also get the response) but I couldn't figure it out how to achieve that.
using System;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
namespace ConsoleClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press a key to start listening");
Console.ReadKey();
var connection = new HubConnectionBuilder()
.WithUrl("wss://api.acme.com/ws")
.AddJsonProtocol()
.Build();
/*
WORK
*/
connection.StartAsync().GetAwaiter().GetResult();
Console.WriteLine("Listening. Press a key to quit");
Console.ReadKey();
}
}
}
Request Message
{ "event": "ping" }
Response Message
{ "event": "pong"}
EDIT : I think I got it wrong. With HubConnectionBuilder class I can only connect to a hub, right? If yes, then how can I connect to ws?
Thanks for any advice.

Related

How to execute RPC calls on all clients when this method sent from one client?

How to execute RPC calls on all clients when this method sent from one client? Is it exists some solution in Unity netcode like RPCTargets.All in Photon?
There you go
using UnityEngine;
using Mirror;
public class ExampleChangeSomething : NetworkBehaviour // ->Inherit from NetworkBehaviour
{
void Start()
{
UI_ChangeSomething();
}
//Attach this to the Button click or call this function from somewhere(e.g. I call this on Start)
public void UI_ChangeSomething()
{
//Client Send command to the Server
Cmd_ChangeSomething("Please Print this Text");
}
//Execute this on Server
[Command]
void Cmd_ChangeSomething(string _text)
{
//The server then tell every Clients to execute the "Rpc_ChangeSomething" Function
Rpc_ChangeSomething(_text);
}
[ClientRpc]
void Rpc_ChangeSomething(string _text)
{
ChangeSomething(_text);
}
//the logic that needs to be executed by Every Client
private void ChangeSomething(string _text)
{
//your logic here.
Debug.Log(_text); // every client will print "Please Print this Text" in their Console
}
}

Disconnect client from IHubContext<THub>

I can call InvokeAsync from server code using the IHubContext interface, but sometimes I want to force these clients to disconnect.
So, is there any way to disconnect clients from server code that references the IHubContext interface?
Step 1:
using Microsoft.AspNetCore.Connections.Features;
using System.Collections.Generic;
using Microsoft.AspNetCore.SignalR;
public class ErrorService
{
readonly HashSet<string> PendingConnections = new HashSet<string>();
readonly object PendingConnectionsLock = new object();
public void KickClient(string ConnectionId)
{
//TODO: log
if (!PendingConnections.Contains(ConnectionId))
{
lock (PendingConnectionsLock)
{
PendingConnections.Add(ConnectionId);
}
}
}
public void InitConnectionMonitoring(HubCallerContext Context)
{
var feature = Context.Features.Get<IConnectionHeartbeatFeature>();
feature.OnHeartbeat(state =>
{
if (PendingConnections.Contains(Context.ConnectionId))
{
Context.Abort();
lock (PendingConnectionsLock)
{
PendingConnections.Remove(Context.ConnectionId);
}
}
}, Context.ConnectionId);
}
}
Step 2:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ErrorService>();
...
}
Step 3:
[Authorize(Policy = "Client")]
public class ClientHub : Hub
{
ErrorService errorService;
public ClientHub(ErrorService errorService)
{
this.errorService = errorService;
}
public async override Task OnConnectedAsync()
{
errorService.InitConnectionMonitoring(Context);
await base.OnConnectedAsync();
}
....
Disconnecting without Abort() method:
public class TestService
{
public TestService(..., ErrorService errorService)
{
string ConnectionId = ...;
errorService.KickClient(ConnectionId);
In alpha 2 there is the Abort() on HubConnectionContext you could use to terminate a connection. I don't see, however, an easy way to access it from outside the hub.
Because you control the clients you could just invoke a client method and tell the client to disconnect. The advantage is that the client disconnect gracefully. The disadvantage is that it requires sending the message to the client instead of disconnecting the client solely on the server side.

Chat Application using SignalR and Ionic

I am developing a chat application.I use SignalR and Ionic for this.And I get an error on the Ionic side.
Startup.cs
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalR.Startup))]
namespace SignalR
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
ChatHub.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalR
{
public class ChatHub : Hub
{
public void Send(string username,string message)
{
Clients.All.sendMessage(username,message);
}
}
}
controller.js
angular.module('starter.controllers', [])
.controller('DashCtrl', function ($scope) {
$scope.name = 'Onur'; // holds the user's name
$scope.message = ''; // holds the new message
$scope.messages = []; // collection of messages coming from server
$scope.chatHub = null; // holds the reference to hub
$scope.chatHub = $.connection.chatHub; // initializes hub
$.connection.hub.start(); // starts hub
// register a client method on hub to be invoked by the server
$scope.chatHub.client.broadcastMessage = function (name, message) {
var newMessage = name + ' says: ' + message;
// push the newly coming message to the collection of messages
$scope.messages.push(newMessage);
$scope.$apply();
};
$scope.newMessage = function () {
// sends a new message to the server
$scope.chatHub.server.sendMessage($scope.name, $scope.message);
$scope.message = '';
};
})
Faield to load resource
hubs(0,0)
TypeError: Cannot read property 'chatHub' of undefined
I'm getting errors.Where am I doing wrong.Help me
You need to start the hub after registering client methods. It should work.

RestSharp for PCL not returning data from ASP.NET Web API

I use this sample tutorial to create a simple Web API.
Then I downloaded the PCL version of RestSharp from here, compiled and tried to execute this test code:
[TestFixture]
public class UnitTest1
{
[Test]
public void TestMethod1()
{
var client = new RestClient("http://localhost:18506/api/");
var request = new RestRequest("products", Method.GET);
client.ExecuteAsync<List<Product>>(request, response =>
{
foreach (var a in response.Data)
{
Console.WriteLine(a.Name);
}
});
}
public class Product
{
public string Name { get; set; }
}
}
Nothing is being written to the console and if I put a break point within the call back, it is not hit.
Any suggestions?
TIA.
You've triggered an asynchronous HTTP call and never seem to be waiting for it to complete. Try waiting or your unit test might finish much before the Web API is even hit by the request:
client.ExecuteAsync<List<Product>>(request, response =>
{
...
}).Result;
But in a unit test you probably don't need to be complicated your life with asynchronous HTTP calls. Just use a standard synchronous call and assert on the results received.

GWT RequestBuilder fails with SSL connections (in tests). Why? Are there any workarounds?

I try to connect to a (local) web service using the GWT RequestBuilder with a secure connection (SSL), but the connection isn't established... When I connect using a plain HTTP connection everything works fine.
Some details
everything works fine when I'm using my browser to view the pages,
I use an auto signed SSL certificate on my local machine,
the tests fail because the actual response code (responseCode) is not set,
the tests work fine if I'm using a plain HTTP connection (no SSL).
Code
package com.example.services;
import com.google.gwt.http.client.*;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Timer;
public class RequestBuilderTest extends GWTTestCase {
private static String SERVER_URL = "https://127.0.0.1/api";
private static final int ASSERT_DELAY_IN_MS = 15000;
private static final int TEST_DURATION_IN_MS = 20000;
private int statusCode;
public void testGet() throws Exception {
new RequestBuilder(RequestBuilder.GET, SERVER_URL).sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable e) {
fail(e.getMessage());
}
public void onResponseReceived(Request request, Response response) {
statusCode = response.getStatusCode();
}
});
delayTestFinish(TEST_DURATION_IN_MS);
new Timer() {
#Override
public void run() {
assertEquals(Response.SC_OK, statusCode);
finishTest();
}
}.schedule(ASSERT_DELAY_IN_MS);
}
#Override
public String getModuleName() {
return "com.example.services.RequestBuilder";
}
}
Results
test passes with SERVER_URL = "http://127.0.0.1/api";
test fails with SERVER_URL = "https://127.0.0.1/api";
This is the stack trace for junit:
junit.framework.AssertionFailedError: Remote test failed at 127.0.0.1
expected=200 actual=0
Any ideas on what could be wrong and how can I make the tests work with SSL?
EDIT
How can I force the tests to run in secure mode? I use eclipse... I tried setting some "Program arguments" in the "Run configurations" (for the junit tests), but they don't work... Here are the arguments:
-noserver -startupUrl https://192.168.8.147/com.example.services.RequestBuilderTest.JUnit/ -bindAddress 0.0.0.0
Is it better if I just deactivate the SSL on the server? These tests are meant to be launched on the continuous integration server and I wanted to test them using SSL.
It sounds like you're running into a same-origin policy problem. Embedding a URL into the app like that is inherently unreliable. Instead, use GWT.getModuleBaseUrl().