Call to MapSignalR causes Protocol error - javascript

this is a follow-up to my previous question here..
MVC - trouble linking to another Controller/Action
as you can see, i eventually did get my view from another controller to display in a new tab so it was working. that is until i installed SignalR. the simple version using this tutorial as a guide..
http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc
the tutorial worked fine after following the steps to create a project. the only thing i had to do to make it work was change the version of the jquery signalr javascript file to the latest (it was one i didn't have because the tutorial was written in older VS 2012).
in any case, after following the same steps for my site, i now get an error when i click the link for /SignalR/SRStart (new tab)..
Protocol error: Unknown transport
playing around i found that this only happens after calling app.MapSignalR() in the startup.cs file. can't understand why since the tutorial i followed worked fine unless it has something to do with crossing over into another controller on that link. it's in the SRStart view that i placed all the signalr connection code and callback function but i don't think it's ever reached since the page doesn't even load.
this is my code..
startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.MapSignalR();
}
}
hub
public class SRHub : Hub
{
public void Send(string message)
{
// Call the addNewMessageToPage method to update clients.
var conn = GlobalHost.ConnectionManager.GetHubContext<SRHub>();
conn.Clients.All.addNewMessageToPage(message);
//Clients.All.addNewMessageToPage(message);
}
}
javascript in SRStart.cshtml
$(function () {
// Reference the auto-generated proxy for the hub.
var conn = $.connection.sRHub;
// Create a function that the hub can call back to display messages.
conn.client.addNewMessageToPage = function (message) {
if (!message.contains('[EOF]')) {
populateStreamDialog(message);
}
};
$.connection.hub.start()
.done(function () {
});
});
any help would be appreciated..

I was able to replicate error. Problem is that /SignalR is route used by SignalR itself.
By using MVC controller named SignalRController there is now conflict between SignalR and MVC causing the error.
Just rename you MVC controller SignalRController (and folder containing its views) to something else...

Related

Embed quicksight through Java sdk

to give a brief about my situation:
Earlier I was using chart.js for creating charts in my dashboard. Then I came across Quicksight a couple of days back. So I thought of switching to it as it provides better handling without any hassle.
Before Quicksight I was using jsp for my page, js(jquery) for my frontend and Java as my backend (spring-boot) with MongoDB as my database.
Keeping my structure same I just defined a jsp so that the user can be directed to the particular page after hitting on the chats.
Then, in my js file, I have written a (my own defined) ajaxRequest that will direct it to the Java controller:
$(document).ready(
function(){
ajaxRequest("/myService/char/getQuickSight", "GET", "", function(response){
})
}
);
Now I am not able to understand how to go on with my controller class. I have written something like this:
private static AmazonQuickSight getClient() {
final AWSCredentialsProvider credsProvider = new AWSCredentialsProvider() {
#Override
public AWSCredentials getCredentials() {
// provide actual IAM access key and secret key here
return new BasicAWSCredentials("access-key", "secret-key");
}
#Override
public void refresh() {
}
};
return AmazonQuickSightClientBuilder.standard().withRegion(Regions.SA_EAST_1.getName())
.withCredentials(credsProvider).build();
}
For he above code I refered to this
It is also throughing an error:
ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: com.amazonaws.client.AwsSyncClientParams.getAdvancedConfig()Lcom/amazonaws/client/builder/AdvancedConfig;] with root cause
java.lang.NoSuchMethodError: com.amazonaws.client.AwsSyncClientParams.getAdvancedConfig()Lcom/amazonaws/client/builder/AdvancedConfig;
(I can also provide the full stacktrace..)
But I am not able to understand how to move forward and what to do with the code. So if anyone can help me out I'll really appreciate it.
P.S. I have also added the following dependency in my POM
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-quicksight</artifactId>
<version>1.11.457</version>
</dependency>

How to take span value from website which stores data dynamically using JavaScript

I am new to this so could anyone point me to the right direction?
I have a JavaScript file by which i want to take the value of a span from a website. Now the website dynamically refreshes the span every 1 second. I am using Java (Eclipse) to fetch this data. When i try to take the span value from website, it gives me no values because the span uses JavaScript to store these values. I already asked this question and i will drop a link below. So all i want to know is, how to take this data dynamically using JSoup. Someone commented on my last post saying the JavaScript might be querying a web service and to find that code. But i could not find the code and i don't know what to do next.
Here is the link to my last question: Fetching Dynamic Website Data Using Java
Here is the link to the website which stores data i want in a span named "id=spot" (Basically numeric numbers of stock): https://www.binary.com/trading?l=EN
And finally here is the link to the JavaScript file of the website which have all the functions: https://static.binary.com/js/binary.min.js?13b386b
Please help me as i am very new to this and i have spent more than 2 days trying to find the answer with no luck.
Thank you in advance
--------------------------------------------------------------------------------.---------------------------------------------------
Okay so the first part of the question is solved but i am having another issue now. I copied this code but i am getting this error now. Here is my code:
import java.net.URI;
import java.io.IOException;
import java.lang.InterruptedException;
import javax.websocket.*;
#ClientEndpoint
public class WSClient {
#OnOpen
public void onOpen(Session session) throws java.io.IOException
{
session.getBasicRemote().sendText("{\"ticks\": \"R_100\"}");
}
#OnMessage
public void onMessage(String message)
{
System.out.println("ticks update: " + message);
}
public static void main(String[] args)
throws IOException, DeploymentException, InterruptedException
{
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
URI apiUri = URI.create("wss://ws.binaryws.com/websockets/v3");
Session session = container.connectToServer(WSClient.class, apiUri);
Thread.sleep(10000);
}
}
And here is the error on console:
Exception in thread "main" java.lang.RuntimeException: Could not find an implementation class.
at javax.websocket.ContainerProvider.getWebSocketContainer(ContainerProvider.java:73)
at WSClient.main(WSClient.java:24)
This site is using WebSockets to retrieve the data from server to show in the client:
var onLoad = function(){
trading_page = 1;
if(sessionStorage.getItem('currencies')){
displayCurrencies();
}
BinarySocket.init({
onmessage: function(msg){
Message.process(msg); //this function is updating that sppan
},
onclose: function(){
processMarketUnderlying();
}
});
Price.clearFormId();
TradingEvents.init();
Content.populate();
So you can not see the data in downloaded HTML with JSOUP. You need a UI-less Browser in java like HTML-UNIT.
But the preferred and more reasonable way is to use the API of the site.

cannot connect to Web API

I am new to WebAPI programming .Here is what have I done
Created ASP.NET web Application SampleWebApiProject in Visual Studio 2013
under .NET Framework 4.5.2
Selected MVC and checked Web API under [Add Folders and core references for].
using Nuget package installed knockout.js ,knockout-validation.js etc etc.
In my code for Login.cshtml I have html button
<div>
<button type="button" class="btn btn-info" data-bind="click:$parent.login">
Login
</button>
</div>
And on my click button I have
self.viewModelHelper.apiPost('api/account/login', unmappedModel,
function (result) {
}
And I have created API Controller called AccountApiController
public class AccountApiController : ApiController
{
[HttpPost]
[POST("api/account/login")]
public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]AccountLoginModel accountModel)
{
return null;
}
}
However when I inspect the click event in Chrome developer tools I get an error response
POST http://localhost:64436/api/account/login 404 (Not Found).
this is my WebApiConfig
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Am I working with right type of application ?
Screenshot
Try:
self.viewModelHelper.apiPost('api/accountapi/login', unmappedModel,
function (result) {
}
and API Controller
public class AccountApiController : ApiController
{
[HttpPost]
[POST("api/accountapi/login")]
public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]AccountLoginModel accountModel)
{
return null;
}
}
Your account controller is named accountapi and not account, so webapi can't find any controller called account.
I'm not sure, but your parameters look wrong in your webapi controller...
Why would you add HttpRequestMessage as a parameter?
You have called your controller AccountApiController and so api/account/login should be accountapi/login
Web API has a strict calls when it comes to MVC architecture.
If you call POST. It means that the API will really CREATE a new Entity, and Does NOT, make other request to be returned.
So meaning, the WebAPI is not custom API function Call that you thought it might be.
It is different from creating an individual API to Creating an web API inside an MVC Application.
Here is are some Notes.
GET : Retrieve an entity
PUT : update an entity
POST : create a new entity
DELETE : remove an existing entity.
so let us say you have an API for Account Models. I will say Models cause when creating an Web API. You need a Model. Unless you're creating your custom API. Outside the MVC.
Now you did this. api/account/test
What it will do is use the [GET] function.
Whatever function you have in the account controllers that have a Data Annotation of [GET] will be executed. And return you something.
And No. Don't use Login as the name of the Method just use GET as you can't really tell the Web API which function to use. It WILL use the one with the GET data annotation. So entering
api/account/ login <---- this will not call the login method, it is entering a string data to be passed to the Get Method.
[HttpGet]
public IEnumerable<string> Get()
{
return "No Value";
}
[HttpGet("{id}")]
public IEnumerable<string> Get(int id)
{
return "There is a value";
}
Now if you want the POST to be Called. Simply create a A Form that has a method of POST. Or JQuery Javascript and call generate the POST method for them. You can't write the Method call in the address bar. You just have to use the right kind of request to call the specific function or function with overload.

Using SignalR to notify current caller

The short version
In my POST action routine, how can I send a notification to some JavaScript running in the client? It seems that SignalR should be an easy solution, but I don't know how to do a callback to the SignalR client that lives in JavaScript in the POST action's client page.
Specifically, it seems that I need a "connection ID" in order to ask SignalR to talk to a specific client, but I don't know how to get one of those either in my POST action or in the client JavaScript.
The whole (not so ugly) story
In my MVC app, my POST action may take a long time to complete. If the POST action decides that it will take a long time to complete, I want to notify some JavaScript on the page so that it can display a "please wait..." notification to the user.
This seems like something that SignalR should make really easy for me. Following the basic tutorial, I added a Hub and created a JS callback in my view:
Note that the Hub has no methods. My client only needs a read-only notification. It has no need to call any methods on the Hub to write message to the outside world.
public class MyHub: Hub
{
}
The view just has a form with a submit button and a hidden "Please wait" message that the SignalR routine can display. The view model has a string property that I can use to pass the SignalR "connection ID" to the POST controller (assuming I can figure out how to get it).
#model SignalRTest.Models.MyViewModel
#using (Html.BeginForm()) {
#Html.HiddenFor(m => m.SignalrConnectionId)
<button type="submit" class="btn btn-primary">Go to it!</button>
}
<div id="hidden-msg" hidden="hidden">
<p>Please wait...</p>
</div>
#section scripts {
<!-- Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!-- Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!-- SignalR script to update the page -->
<script>
$(function () {
// Get a reference to the server "hub" class (camelCase)
var hub = $.connection.interviewDoneHub;
// Get our connection ID and store it in a hidden field
// so that it is sent to the POST action
// var connectionId = $.connection.hub.id; //This doesn't work!
// $('##Html.IdFor(m => m.SignalrConnectionId)').attr(connectionId, '');
// Create a function that the hub can call
hub.client.myCallback = function () {
$('#hidden-msg').show();
};
// Start the connection.
$.connection.hub.start().done(function () {
});
});
</script>
}
Meanwhile back in my POST controller action, I call the JS callback:
[HttpPost]
public async Task<ActionResult> MyAction(MyViewModel model)
{
// We've decided that this will take a while. Tell the client about it...
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.myCallback();
//context.Clients.Client(model.SignalrConnectionId).myCallback();
await Task.Delay(2000);
return RedirectToAction("NextPage");
}
Now, my problem: As a proof-of-concept test, I use this code to call the JS callback:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.myCallback();
which works just dandy. But, obviously, I want to call the specific client associated with the POST action. C# Intellisense tells me that I should be able to call
context.Clients.Client("connectionId").myCallback();
but I can't figure out how to get the desired "connectionId" string. I don't think I'll be able to get the client ID in the POST controller because I don't have any sort of SignalR connection to the client at that point. I figured I'd let the client get its connection ID and give it to the POST controller in the view model, but I haven't found the magic JS code that fetches the connection ID out of the SignalR framework.
I found several SO articles that stated matter-of-factly:
connectionId = $.connection.hub.id;
but this returns undefined. I found this SignalR JS Client Wiki page, which says:
connection.id
Gets or sets the client id for the current connection
but that also returns undefined.
Which gets back to my original question. Maybe I'm not understanding something fundamental about what a connection ID is...
Okay I believe I see what the issue is. You want to start the your connection in javascript
$.connection.hub.start()
After you do that, then your should be able to do connection.hub.id - if the connection is not started then there will be no connection id at all, which is why you are getting an "undefined" value because it has not been set until you start the connection.
Actually this could be a bastardization of things, not sure if it will work but should require minimal changes to your code. Each time a client connects to your hub you can add this to the connect method
Groups.Add(Context.ConnectionId, Context.ConnectionId);
// name it the same as your connection id since that is the identified you are using
Then in your controller you can add the following in your action call
var context = GlobalHost.ConnectionManager.GetHubContext<InterviewDoneHub>();
context.Clients.Groups(connectionId).myCallback();
If the above does not work then you are going to have to connect to the hub using .NET Client. Just like you connected from javascript you can connect to the hub using C# and call a method that will then notify the client you want notified. I did this using WebAPI in the past but I am fairly certain that it can be done in Asp.Net MVC as well.
Thanks to GJohn for the reference to the .NET Client docs, which contain this example:
$.connection.hub.start()
.done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
.fail(function(){ console.log('Could not Connect!'); });
});
So, it turns out that $.connection.hub.id does, in fact, return the connection ID. But I was trying to call that routine at page load time, before the connection is established! The correct JS code for my view looks like this:
#section scripts {
<!-- Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!-- Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!-- SignalR script to update the page -->
<script>
$(function () {
// Get a reference to the server "hub" class (camelCase)
var hub = $.connection.interviewDoneHub;
// Create a function that the hub can call
hub.client.myCallback = function () {
$('#hidden-msg').show();
};
// Start the connection.
$.connection.hub.start()
.done(function () {
// Get our connection ID and store it in a hidden field
// so that it is sent to the POST action
$('##Html.IdFor(m => m.SignalrConnectionId)').attr('value', $.connection.hub.id);
})
.fail(function () { });
});
</script>
}
But now I have a minor problem: I need to add a bit more JS code to disable the submit button when the form loads, and re-enable it in the connection "done" function; otherwise the user can click on the submit button before the connection ID exists. I'll leave that as an exercise for the reader...

value from javascript is not returning to c# in the application in Visual Web GUI

I have written a java script function in the skin file of the visual web Gui application which returns some value too. Now i am invoking the java script method from code behind.
public void XYZ( string message)
{
this.InvokeMethodWithId("testCall", message);
}
And javascript function is:--
function testCall(strGuid, txt) {
alert("hai Java script fired..");
return txt+ 'returned from JavaScript';
}
I want the value returned from JavaScript in the application. how can i achieve it. Is there in other method to invoke the methods of JavaScript?
I want something like this:--
public void Conect( string message)
{
string returnedvalue = this.InvokeMethodWithId("testCall", message);
}
Javascript is executed on the client so the return won't make it to the server.
A solution could be to use AJAX to send that value to the server. Stack Overflow is full of answers about AJAX.
Here's a good example.
#Amish Kumar,
As noted by other replies already, the client-side and server-side are not directly connected in web programming. The client is always the initiator of every request, and the server-side's "purpose" is to render a response, which will then be returned to the client for processing, in Visual WebGui this is usually some UI update processing. This basically means that your client script will not execute until the server-side has finished rendering the response, and the only way the client can get some message back to the server is to issue another request.
Think about how you need to use the MessageBox in Visual WebGui for instance. In order to receive the "response" from the MessageBox, you need to supply a callback handler in your server-side code, and then your server-side code will have completed creating the response, which is returned to the client. The client updates its UI and on some action to the MessageBox dialog, it sends a new request to the server, which interpretes the action and invokes your callback handler. In the callback handler you use Form.DialogResult to get the user action.
A very basic way to make this work in custom Visual WebGui code could be like the following code on a Form:
private void button1_Click(object sender, EventArgs e)
{
SendClientMessage("This is a test");
}
public void SendClientMessage(string strMessage)
{
System.Text.StringBuilder sb = new StringBuilder();
sb.AppendLine("var objEvent = mobjApp.Events_CreateEvent('{0}', 'MessageEvent');");
sb.AppendLine("mobjApp.Events_SetEventAttribute(objEvent, 'Msg', '{1}');");
sb.AppendLine("mobjApp.Events_RaiseEvents();");
this.InvokeScript(string.Format(sb.ToString(), this.ID, strMessage));
}
protected override void FireEvent(Gizmox.WebGUI.Common.Interfaces.IEvent objEvent)
{
if (objEvent.Type == "MessageEvent")
MessageBox.Show(objEvent["Msg"]);
else
base.FireEvent(objEvent);
}
This code will not work unless you set your Visual WebGui applicaton for no Obscuring. In order for this code to work on an obscured application, you would need to add the JavaScript as an obscured JavaScript resource and it would work fine.
Palli
enter code here

Categories