Does Memgrpah support connections over WebSocket? I couldn't find the minimal required code to do that.
All that you need is a client that uses WebSocket to connect to Memgraph, and Memgraph will automatically recognize the nature of the connection. The port you will be connected to remains the same.
You should use Memgraph's address and the port number defined by the configuration flag --bolt-port to connect to Memgraph (7687 is the default port).
To connect to memgraph via WebSocket you can use the JavaScript client. Minimal code to connect would be:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Javascript Browser Example | Memgraph</title>
<script src="https://cdn.jsdelivr.net/npm/neo4j-driver"></script>
</head>
<body>
<p>Check console for Cypher query outputs...</p>
<script>
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("", "")
);
(async function main() {
const session = driver.session();
try {
await session.run("MATCH (n) DETACH DELETE n;");
console.log("Database cleared.");
await session.run("CREATE (alice:Person {name: 'Alice', age: 22});");
console.log("Record created.");
const result = await session.run("MATCH (n) RETURN n;");
console.log("Record matched.");
const alice = result.records[0].get("n");
const label = alice.labels[0];
const name = alice.properties["name"];
const age = alice.properties["age"];
if (label != "Person" || name != "Alice" || age != 22) {
console.error("Data doesn't match.");
}
console.log("Label: " + label);
console.log("Name: " + name);
console.log("Age: " + age);
} catch (error) {
console.error(error);
} finally {
session.close();
}
driver.close();
})();
</script>
</body>
</html>
You can find more info at Memgraph documentation site.
Related
I am using GooglePicker with React, and the result I am getting is an array of objects...
[
{
"id": "1...m",
"serviceId": "docs",
"mimeType": "image/jpeg",
"name": "name.jpg",
"description": "",
"type": "photo",
"lastEditedUtc": 1575388407136,
"iconUrl": "https://drive-thirdparty.googleusercontent.com/16/type/image/jpeg",
"url": "https://drive.google.com/file/d/1...m/view?usp=drive_web",
"embedUrl": "https://drive.google.com/file/d/1...m/preview?usp=drive_web",
"sizeBytes": 111364,
"rotation": 0,
"rotationDegree": 0,
"parentId": "0...A"
}]
So I tried to access through https://www.googleapis.com/drive/v3/files and directly through file.url using
const fetchOptions = { headers: { Authorization: `Bearer ${accessToken}` } };
docs.forEach((file) => {
...
fetch(file.url, fetchOptions).then((res) => {
const blob = res.blob();
uploadFile(blob);
});
});
But I get 403 or CORS; I tried setting the relayUrl in the picker, but this broke the Picker.
Notes:
I have these 3 scopes in my auth2:
['https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.readonly']```
I have my computer's url with port and protocol set as Authorized JavaScript origins and Authorized redirect URIs
Any ideas?
Edit 1:
I also tried using Google API like this:
const FILE_URL = 'https://www.googleapis.com/drive/v3/files';
const url = isDoc
? `${FILE_URL}/${file.id}/export?mimeType=${mimeType}`
: `${FILE_URL}/${file.id}?alt=media`;
fetch(url, fetchOptions).then((res) => {
const blob = res.blob();
uploadFile(blob);
});
You'll need the Drive API
From your question it seems that you are trying to do everything with Google Picker. However, the picker will only get you limited metadata for the files, so you can open them with your account (i.e. see them in another window) or let you upload files. If you want to download the actual file, then you will need to use the Drive API.
Drive Quickstart for browser JavaScript
The flow might be:
let user pick file
get metadata object
extract file id from object
make a call to Drive API (get with alt='media')
If I have misunderstood and you are already using the Drive API, then it would be helpful to see the associated code with that.
Ref
Quickstart
get
export)
EDIT:
Here is an example of using the Picker API to feed into the Drive API with gapi using the same login client.
HTML
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
</head>
<body>
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<div id="result"></div>
<script type="text/javascript" src="script.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
JS
const API_KEY = 'AI...';
const CLIENT_ID = '44...';
const appId = "44...";
const SCOPES = ["https://www.googleapis.com/auth/drive"];
const DISCOVERY_DOCS = [
"https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
];
const authorizeButton = document.getElementById("authorize_button");
const signoutButton = document.getElementById("signout_button");
// Use the Google API Loader script to load the google.picker script.
function handleClientLoad() {
gapi.load("client:auth2:picker", initClient);
}
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES[0]
})
.then(
function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(handleSignIn);
// Handle the initial sign-in state.
handleSignIn(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
},
function (error) {
appendPre(JSON.stringify(error, null, 2));
}
);
}
function handleSignIn(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = "none";
signoutButton.style.display = "block";
createPicker();
} else {
authorizeButton.style.display = "block";
signoutButton.style.display = "none";
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function createPicker() {
const token = gapi.client.getToken().access_token
if (token) {
let view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
let picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(token)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(API_KEY)
.setCallback(getFile)
.build();
picker.setVisible(true);
}
}
function getFile(pickerResp) {
gapi.client.drive.files
.get({
fileId: pickerResp.docs[0].id,
alt: 'media'
})
.then(resp => {
console.log("fetch response", resp.status)
let binary = resp.body
// EDIT - addition from Gabrielle vvvv
let l = binary.length
let array = new Uint8Array(l);
for (var i = 0; i<l; i++){
array[i] = binary,charCodeAt(i);
}
let blob = new Blob([array], {type: 'application/octet-stream'});
// EDIT - addition from Gabrielle ^^^^
}
This code is adapted from the Drive Quickstart and the Picker Quickstart.
Note - this does give an error in the console, but it does seem to work all the same. This does seem to be a bug with the Picker - https://issuetracker.google.com/177046274
EDIT from Gabrielle
Note - using get with alt = media is for binary files. To get sheets/docs/slides etc, you need to use the export end point.
This is a follow up to a question I posted earlier on parsing xAPI statements. I got the parsing to work and now I'm using the code below to get statements from the ADL LRS and it pulls the first 50 records. Is there a way to specify more records? Thank you.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Get my Statements</title>
<script type="text/javascript" src="tincan.js"></script>
</head>
<body>
<h1>Get statements</h1>
<div id='response'></div>
<script>
var tincan = new TinCan (
{
recordStores: [
{
endpoint: "https://lrs.adlnet.gov/xapi/",
username: "xapi-tools",
password: "xapi-tools",
allowFail: false
}
]
}
);
var container = document.getElementById('response');
tincan.getStatements({
'callback': function (err, result) {
container.innerHTML = (err !== null ? 'ERROR' : parseMyData(result));
}
});
parseMyData = function(result) {
var statements = result.statements;
var output = '';
var name,verb,activity;
for(var i=0;i<statements.length;i++){
// check the statement for a usable name value
// (priority = actor.name, actor.mbox, actor.account.name)
if(statements[i].actor.name != null && statements[i].actor.name != "") {
name = statements[i].actor.name
}else if(statements[i].actor.mbox != null && statements[i].actor.mbox != "") {
name = statements[i].actor.mbox
}else{
name = statements[i].actor.account.name
}
// check the statement for a usable verb value
// (priority = verb.display['en-US'], verb.id)
try{
verb = statements[i].verb.display['en-US'];
}catch(e){
verb = statements[i].verb.id;
}
// check the activity for a usable value
// (priority = definition.name['en-US'], id)
try{
activity = statements[i].target.definition.name['en-US'];
}catch(e){
activity = statements[i].target.id;
}
output += name + ' - ' +
verb + ' - ' +
activity +
'<br>'
}
return output;
}
</script>
</body>
</html>
More records would be in the request itself. Look at the API documentation, most times there is a parameter you can pass for records to be retrieved.
Use the code below to request statements with a set limit per page. If you make a request without a limit parameter or a limit of 0, then the maxmimum number of statements allowed by the server will be returned in the first page (this is what you are already doing above).
tincan.getStatements({
params: {
limit: 100
},
'callback': function (err, result) {
container.innerHTML = (err !== null ? 'ERROR' : parseMyData(result));
}
See https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#stmtapiget
To get additional pages of statements use the TinCanJS LRS moreStatements method: https://github.com/RusticiSoftware/TinCanJS/blob/master/src/LRS.js#L766
See http://rusticisoftware.github.io/TinCanJS/ for how to create the LRS object.
I'm working on a project where I'm sending temperature data via Arduino to a Node server. Arduino sends data to the server through URL parameters:
http://localhost:3000/submit?temprature=25
I'm then fetching the posted data using the following Node server.js
var express = require('express');
url = require('url');
var app = express();
app.get('/submit', function(req, res){
var data = url.parse(req.url,true).query;
console.log(data);
});
app.listen(3000, function(){
console.log('listening on *:3000');
});
I'm able to show the required data with console.log(), but what I want is, as soon as Arduino sends the data through URL parameters, that data should automatically echo/print on the server: http://localhost:3000/index.html like in real time. How can I achieve this?
You can use socket.io to emit events every time the temperature is updated by your arduino device:
var http = require('http');
var url = require('url');
var express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server); //pass a http.Server instance
server.listen(3000);
app.get('/submit', function(req, res){
var data = url.parse(req.url,true).query;
io.emit('temperature', data);
res.send('Temperature Updated to: ' + data.temperature);
});
app.get('/index', function(req, res){
res.sendFile(__dirname + '/public/index.html');
});
Then on the client side, you can listen for events and update the information. This is public/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.IO Temperature Example</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
</head>
<body>
<h1 id="temperature"></h1>
<script>
var socket = io('http://localhost:3000');
socket.on('temperature', function (data) {
console.log(data);
$('h1#temperature').html(data.temperature);
});
</script>
</body>
</html>
I have designed a chat application based on websocket protocol.
i have installed a xampp server in computer A .I start the server in computer A and then I am trying to access client.php page (url is ipadresssofA/project/client.php) from computer B using the ip address of computer A. But it is displaying socket error.
And when i try same url on computer A (url is ipadresssofA/project/client.php). client get connects.BOTH COMPUTERS ARE CONNECTED WITH SAME WIFI.
Here is my client code.please tell me what is wrong
<html>
<head>
<style>
#chatlog {width:440px; height:200px; border:1px solid;overflow:auto;}
#userslog {width:440px; height:200px; border:1px solid;overflow:auto;}
#msg {width:330px; height:100px;}
</style>
<script>
function initialize(){
var host = "ws://localhost:12345/project/server3z.php";
try{
socket = new WebSocket(host);
chatlog('WebSocket - status '+socket.readyState);
socket.onopen = function(event){chatlog("WebSocket status "+this.readyState); };
socket.onmessage = function(event){ chatlog(event.data); };
socket.onclose = function(){ chatlog("WebSocket status "+this.readyState); };
socket.onerror = function(event){chatlog("Error :"+event.data); };
}
catch(err){ chatlog(err); }
}
function send()
{
var chat;
chat= document.getElementById("msg").value;
if(!chat){ alert("Message can not be empty"); return; }
try{ socket.send(chat); chatlog('Sent: '+chat); } catch(err){ log(err); }
document.getElementById("msg").value = "";
}
function quit(){
chatlog("closed!");
socket.close();
chatlog("WebSocket status "+socket.readyState);
}
function chatlog(msg)
{
var match=msg.match(/10101010101010/g);
if(match)
{
var msg=msg.split("10101010101010");
document.getElementById("userslog").innerHTML+="<br>"+msg[0];
}
else
{
document.getElementById("chatlog").innerHTML+="<br>"+msg;
}
}
function onkey(event){ if(event.keyCode==13){ send(); } }
</script>
</head>
<body onload="initialize()">
<center>
<div id="chatlog"></div>
<input id="msg" type="textbox" onkeypress="onkey(event)"/>
<button onclick="send()">Send</button>
<button onclick="quit()">Stop</button>
<div id="userslog"></div>
</center>
</body>
</html>
Also in my server code something is written in comments which i want to show you :
// start the server
$Server = new PHPWebSocket();
$Server->bind('message', 'wsOnMessage');
$Server->bind('open', 'wsOnOpen');
$Server->bind('close', 'wsOnClose');
// for other computers to connect, you will probably need to change this to your LAN IP or external IP,
// alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME']))
$Server->wsStartServer('localhost', 12345);
Initialize var host as follows:
var host = "ws://localhost:12345";
Everything else looks ok.
I'm trying PhoneGap/Cordova 2.1.0 in WP7 for the first time, so I'm new in this.
What I should do is capturing a picture through the camera and uploading it to a server.
This is my code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>PhoneGap WP7</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.1.0.js"></script>
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() { }
function capturePhoto()
{
// Take picture using device camera and retrieve image
navigator.camera.getPicture(
onPhotoDataSuccess,
onFail,
{
quality: 50,
destinationType: Camera.DestinationType.DATA_URL
}
);
}
function onPhotoDataSuccess(imageData)
{
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageData.substr(imageData.lastIndexOf('/') + 1);
options.mimeType="image/jpeg";
var params = new Object();
options.params = params;
var ft = new FileTransfer();
ft.upload(imageData, "http://mysite.com/upload.php", win, fail, options);
}
function onFail(message)
{
navigator.notification.alert('Failed because: ' + message);
}
var win = function(r)
{
navigator.notification.alert(r.responseCode + " - " + r.response + " - " + r.bytesSent);
}
var fail = function(error)
{
navigator.notification.alert(eval(error));
}
</script>
</head>
<body>
<h1>PhoneGap Photo Demo</h1>
<button onclick="capturePhoto();">Capture a Photo</button>
</body>
</html>
When I try this, the upload doesn't work and I get an empty error object:
{ "code":null, "source":null, "target":null, "http_status":null }
Some notes:
I followed this trick for missing whitelist in WP7.
The php code is not written by me, I would do it in asp.net, if someone could provide a working example with an asp.net webservice would be really appreciated.
Thanks.
EDIT
I debugged FileTransfer class and I get an error in JsonHelper class:
using (MemoryStream mem = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
result = deserializer.ReadObject(mem);
}
The error is: InvalidCastException
EDIT
Try replacing
uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions[]>(options)[0];
with the the following
options = JSON.JsonHelper.Deserialize<string[]>(options)[0];
uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(options);
ORIGINAL ANSWER
The easiest way to troubleshot such issues is to add reference to Cordova library source code instead of compiled WP7CordovaClassLib.dll
cordova-2.1.0-incubating-src\cordova-2.1.0\incubator-cordova-wp7\framework\WP7CordovaClassLib.csproj
http://www.apache.org/dist/incubator/cordova/
and then add breakpoint to standalone\cordovalib\Commands\FileTransfer.cs
/// <summary>
/// sends a file to a server
/// </summary>
/// <param name="options">Upload options</param>
public void upload(string options)
{
Debug.WriteLine("options = " + options);
options = options.Replace("{}", "null");
Sounds complex, but from my experience line by line debugging is the simplest way to understand what particular goes wrong with Apache Cordova in many situations.