I'm trying to connect my javascript WebSocket to the backend.
I'm using this HTTP Hijack https://gist.github.com/missedone/76517e618486db746056
My Java code get's the response correctly System.out.println(response); (so there's connection) but this is not what I want.
I want to connect the backend (java) to the frontend (jquery/javascript) so I can send commands though the terminal instead of the current implementation
I'm only missing a way to connect this HttpHijack in the backend to my WebSocket in the front end.
Any help?
Java
public String execConsole(String containerName) {
Settings settings = Settings.getSettings();
Container container = getContainer(containerName);
//exec
ExecCreateCmdResponse execCreateResp = dockerClient().execCreateCmd(container.getId()).withCmd("bash")
.withAttachStderr(true).withAttachStdout(true).withAttachStdin(true).withTty(false).exec();
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
HttpHijack ws = null;
try {
ws = new HttpHijack(new URI("http://" + settings.getDockerIP() +":"+ settings.getDockerPort() +"/v1.19/exec/" + execCreateResp.getId() + "/start"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
String payload = "{\"Detach\": false,\"Tty\": false}";
try {
ws.post(headers, payload);
} catch (IOException e) {
e.printStackTrace();
}
String request = "date > /tmp/nick2; cat /tmp/nick2; exit $?;";
InputStream input = null;
try {
input = ws.send(request);
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
InspectExecResponse execResp = dockerClient().inspectExecCmd(execCreateResp.getId()).exec();
System.out.println("exec inspect: {}" + execResp);
try {
String response = IOUtils.readLines(input).toString();
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
Javascript
$('#btnConnect').click(function () {
$.ajax({
url: '/connect-console',
type: 'post',
data: {containerName: containerName},
success: function (url) {
$('#connectDiv').hide();
$('#terminalDiv').show();
term = new Terminal({
screenKeys: true,
useStyle: true,
cursorBlink: true
});
ws = new WebSocket(url,true);
ws.binaryType = 'arraybuffer';
term.on('data', function (data) {
ws.send(data);
});
term.open(document.getElementById("terminal"), true);
ws.onopen = function() {
console.log('ws connected');
};
ws.onerror = function() {
console.log('ws error');
};
ws.onclose = function() {
console.log('ws closed');
};
ws.onmessage = function(evt) {
var decoder = new TextDecoder('utf-8');
var data = decoder.decode(evt.data);
term.write(data);
};
}
});
});
Related
I am trying to get web sockets working inside a Asp.Net Core app that is hosted under nginx inside Raspberry Pi.
My default file settings are:
location /the_socket/ {
proxy_pass http://websocket:8090/;
}
in class the websocket (using Fleck) is opened like:
var server = new WebSocketServer("ws://0.0.0.0:8090/the_socket");
server.Start(
socket =>
{
socket.OnOpen = () =>
{
};
socket.OnClose = () =>
{
};
socket.OnMessage = message =>
{
};
});
This is my calling JavaScript:
url = "ws://the_socket:8090";
$(document).ready(function () {
function Connect() {
try {
$("#lblConnectionStatus").html("Reconnecting...");
if (ws instanceof WebSocket) {
ws.close();
}
ws = new WebSocket(url);
ws.binaryType = "arraybuffer";
ws.onerror = function (e) {
$("#divInternalMessangingStatus").html("Internal Messaging Error: " + e.message);
};
ws.onclose = function () {
$("#divInternalMessangingStatus").html("Internal Messaging Closed:");
Connect();
};
ws.onopen = function () {
$("#divInternalMessangingStatus").html("Client connected");
};
ws.onmessage = function (e) {
$("#divInternalMessangingStatus").html(e.data);
};
} catch (err) {
$("#divInternalMessangingStatus").html(err);
}
}
Connect();
});
Which errors on Connection Refused...
NB
I had tried changing:
location /the_socket/ {
proxy_pass http://websocket:8090/;
}
to:
location /the_socket/ {
proxy_pass http://0.0.0.0:8090/;
}
following code gets error "result undefined" (last error trap) please help:
try {
var driver = neo4j.driver("bolt://localhost:7474", neo4j.auth.basic(userName, passWord));
} catch (err) {
alert(err.message);
}
const session = driver.session();
const personName = 'Alice';
try {
const resultPromise = session.run('CREATE (a:Person {name: $name}) RETURN a', {
name: personName
});
} catch (err) {
alert(err.message);
}
try {
resultPromise.then(
result => {
session.close();
const singleRecord = result.records[0];
const node = singleRecord.get(0);
console.log(node.properties.name);
driver.close();
}
);
} catch (err) {
alert(err.message);
}
I think the error is due to the fact that you are using the java bolt driver on the http port (7474) of Neo4j.
Just change the connection url by this one : neo4j.driver("bolt://localhost:7687", neo4j.auth.basic(userName, passWord))
My calls to the server are built in the following way:
I have a callServer function on the client that sends data to my API;
My API then receives the data from it's controller and pass it to a function that makes a call to the DB;
The controller sends the response back to the client.
This is how I do it (these are just the important pieces of the code, not everything is here):
API (Context.cs):
public static IEnumerable<Dictionary<string, object>> Proc_example(int? value)
{
using (NpgsqlConnection conn = new NpgsqlConnection(ConnStr))
{
try
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "proc_example";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new NpgsqlParameter("value", convertNullValue(value)));
var reader = cmd.ExecuteReader();
return new DrToDictionary().Serialize(reader);
}
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
API (Controller.cs):
[Authorize]
public JsonResult example(int? value)
{
try
{
var data = Context.Proc_example(value);
return Json(new AppServerResult()
{
Result = new { list = data }
}, JsonRequestBehavior.AllowGet);
}
catch (Exception e)
{
return Json(new AppServerResult()
{
HasError = true,
ErrorMessage = "Houve um erro ao consultar, tente novamente."
});
}
}
Client (callServer):
app.callServer = function (options, sucessCallback, httpErrCallback, serverErrCallback, operationErrorCallback) {
if (options.source == undefined)
options.headers = { "Authorization": $.cookie('Token') }
options.success = function (result) {
try {
var _result = result;
if (typeof _result == "string") {
_result = jQuery.parseJSON(_result);
}
if (typeof _result.HasError != "undefined" && _result.HasError) {
if (!_result.IsValidationError) {
if (typeof __apiCallerErrorCallback == "function")
__apiCallerErrorCallback(_result.ErrorMessage);
if (typeof serverErrCallback == "function") {
serverErrCallback(_result.ErrorMessage);
}
} else {
app.notifyValidationException(_result.ErrorMessage);
}
} else {
if (typeof sucessCallback == "function") {
if (_result.Result != undefined) sucessCallback(_result.Result);
else sucessCallback(_result);
}
}
} catch (ex) {
throw ex;
}
};
options.error = function (result) {
if (typeof httpErrCallback == "function") {
httpErrCallback();
}
if (typeof __apiCallerErrorCallback == "function")
__apiCallerErrorCallback("HTTP Error");
}
};
jQuery.ajax(options);
};
Calling example:
callingTheServerExample = function (callback, value) {
app.callServer({
type: "POST",
url: app.webAPIRootPath + "Controller/example",
data: "{ 'value':" + JSON.stringify(ko.toJS(value)) + " }",
contentType: "application/json; charset=utf-8",
dataType: "json"
}, function (result) {
if (typeof callback == "function")
callback(result);
});
}
My problem is that when my JSON gets too large, my API gives me a JsonMaxLength exception when sending tha data back to the client (the exception happens on the controller class). I'd prefer not to set my maxJsonLength to a higher value. Instead, I'd like to find a way to send my JSON in chunks from the API and mount it on the client through javascript.
Is there a way to do it?
EDIT:
I forgot to add a detail: I'm using a REST API. As stated in the comments below, pagination is a solution, but what I need is to get the whole record set to be available at once. It's possible to do it using pagination, but it seems to be slower and to cause more API calls. Streaming appears to be a solution, but I never did this before and I can't figure out how to implement it.
EDIT 2:
I've implemented my paging like this:
public JsonResult example(int? value, int page)
{
try
{
var data = Context.Proc_example(value, page);
if (pPage > 0)
{
var pagedResult = data.Skip((page - 1) * 20).Take(20).ToList();
return Json(new AppServerResult()
{
Result = new { list = data}
}, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new AppServerResult()
{
Result = new { list = data}
}, JsonRequestBehavior.AllowGet);
}
}
catch (Exception e)
{
return Json(new AppServerResult()
{
HasError = true,
ErrorMessage = "Houve um erro ao consultar, tente novamente."
});
}
}
But I still didn't achieve what I wanted. Would someone think of a better way?
for JsonMaxLength exception
Try
write in web.config
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="1000000">
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
By default the maxJsonLength is 102400.
I am trying to create web-sockets in APEX for automatic refresh with node
but I am getting error This is not valid JSON:
java script code
$(function(){
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket) {
console.log('Sorry websockets');
}
else {
var connection = new WebSocket('ws://127.0.0.1:1337');
connection.onerror = function (error) {
console.log( 'Sorry, but there is some problem with your connection or the server is down.');
};
connection.onmessage = function (message) {
console.log(message.data);
try {
var json = JSON.parse(message.data);
if (json.message=='REFRESH') {
gReport.pull();
}
else {
console.log(json.message);
}
}
catch (e) {
console.log('Thisnot valid JSON: ' + message.data);
}
};
}
});
Hi all I am trying to display the words "hello JSON" on my web page but it's displaying the full string { "msg": "Hello JSON." }. I know why it is doing that, but how can I get it to display just hello JSON without just plopping it into an html script and using just that?
This is my code:
var http = require('http');
var domain = require('domain');
var root = require('./message'); // do I have to replace root w/ message
var image = require('./image'); // for better readability?
function replyError(res) {
try {
res.writeHead(500);
res.end('Server error.');
} catch (err) {
console.error('Error sending response with code 500.');
}
};
function replyNotFound(res) {
res.writeHead(404);
res.end('not found');
}
function handleRequest(req, res) {
console.log('Handling request for ' + req.url);
if (req.url === '/') {
root.handle(req, res);
}
if (req.url === '/image.png'){
image.handle(req, res);
} else {
replyNotFound(res);
}
}
var server = http.createServer();
server.on('request', function(req, res) {
var d = domain.create();
d.on('error', function(err) {
console.error(req.url, err.message);
replyError(res);
});
d.run(function() { handleRequest(req, res)});
});
server.listen(5000);
then message.js or root (in min var root = require(/message)
var http = require('http');
var body;
exports.handle = function(req, res) {
res.writeHead(200, {
'Content-Type': 'application/json',
'Content-Length': body.length
});
res.end(body);
};
exports.init = function(cb) {
require('fs').readFile('app.html', function(err, data) {
if (err) throw err;
body = data;
cb();
});
}
app.html
<html>
<header><title>This is title</title></header>
<body>
Hello world
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
Make a request
</span>
<script type="text/javascript">
(function() {
var httpRequest;
document.getElementById("ajaxButton").onclick = function() { makeRequest('message.js'); };
function makeRequest(url) {
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
if (!httpRequest) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
httpRequest.onreadystatechange = alertContents;
httpRequest.open('GET', url);
httpRequest.send(msg);
}
function alertContents() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
})();
</script>
</body>
</html>
Try changing body = data; to body = data.msg; in you 'message.js' file. This will lookup the value for the key, msg, in the JSON object and assign the result to the body variable.
edit
In your alertContents function, replace:
alert(httpRequest.responseText);
with:
var resData = JSON.parse(httpRequest.ResponseText);
alert(resData.msg);
What this does is parse the JSON response into a Javascript object and then looks up the msg attribute and uses that for the alert.
edit 2
Any time that you need to parse JSON, use JSON.parse(jsonString). It will return a native JavaScript object that you can store in a variable and look up attributes on, as in the example above.
I cannot see where you're receiving the msg from but at the place where you receive the JSON string just do this.
var jsonResult = receivedData();
if (jsonResult && jsonResult.msg)
{
alert(jsonResult.msg);}
}