I've written my first program with racer. It displays a simple text box manually bound to 'col.doc.prop' path. When I change the value, it does not apply to the store at server.
What causes my subscribed model not to get sync with server?
Server code:
var fs = require('fs');
var io = require('socket.io');
var racer = require('racer');
var mongo = require('racer-db-mongo');
racer.use(mongo);
racer.js({
entry: __dirname + '/client.js'
}, function(err, js) {
return fs.writeFileSync(__dirname + '/script.js', js);
});
var express = require('express');
var server = express.createServer();
server.use(express.static(__dirname));
server.get('/', function(req, res)
{
var model = store.createModel();
model.subscribe('col.doc', function(err, doc)
{
var prop = doc.get('prop');
if (!prop)
{
doc.set('prop', 123);
store.flush();
}
model.ref('_doc', doc);
model.bundle(function(bundle)
{
var client = require('fs').readFileSync('./client.html', 'utf-8');
client = client.replace('_init_', bundle.toString());
res.send(client);
});
});
});
var store = racer.createStore(
{
listen: server,
db:
{
type: 'Mongo',
uri: 'mongodb://localhost/racerdb'
}
});
store.set('col.doc.prop', 123);
store.flush();
server.listen(3001);
Client code:
useRacer = function()
{
var socket = io.connect('http://localhost:3001');
var racer = require('racer');
process.nextTick(function() {
racer.init(this.init, socket);
return delete this.init;
});
racer.on('ready', function(model)
{
addListener = document.addEventListener ? function(el, type, listener) {
return el.addEventListener(type, listener, false);
} : function(el, type, listener) {
return el.attachEvent('on' + type, function(e) {
return listener(e || event);
});
};
var element = document.getElementById('prop');
var listener = function()
{
var val = element.value;
model.set('col.doc.prop', val);
};
addListener(element, 'keyup', listener);
var upgrade = function(id, value)
{
if (model.connected)
{
var prop = model.get('col.doc.prop');
element.value = prop;
}
else
model.socket.socket.connect();
};
model.on('connectionStatus', upgrade);
model.on('set', 'con.*', upgrade);
});
};
The problem solved by changing some lines of the client code:
model.set('col.doc.prop', val) ==> model.set('_doc.prop', val)
model.get('col.doc.prop') ==> model.get('_doc.prop')
model.on('set', 'con.', upgrade) ==> model.on('set', '', upgrade)
Related
controller on localhost:8000
const fs = require("fs");
exports.install = function () {
ROUTE("GET /", indexPage);
};
function indexPage() {
var self = this;
console.log(" In GET ROUTE");
RESTBuilder.GET("http://127.0.0.1:8500/getFile/").stream(function (
err,
response
) {
if (err) {
console.log(err);
return;
}
var writer = fs.createWriteStream("./public/testBuilder.txt");
// console.log("Writing to file");
response.pipe(writer);
self.json({ thankyou: "ok" });
});
}
controller on localhost:8500
exports.install = function () {
ROUTE("GET /getFile/", test);
};
function test() {
var self = this;
console.log("#################");
console.log(self.body);
self.file("~trimSail/restBuilder.txt");
// });
}
above code works in totaljs 3 but failing in total4.
sending a file in response to RestBuilder.GET and streaming the response to file.
error response.pipe is not a function.
First of all, please clean your code.
Total.js guidelines https://docs.totaljs.com/welcome/67b47001ty51c/
Optimized for Total.js:
const Fs = require('fs');
exports.install = function () {
ROUTE('GET /', index);
};
function index() {
var $ = this;
console.log('In GET ROUTE');
RESTBuilder.GET('http://127.0.0.1:8500/getFile/').stream($.successful(function(response) {
var writer = Fs.createWriteStream('./public/testBuilder.txt');
response.stream.pipe(writer);
$.json({ thankyou: 'ok' });
}));
}
While creating a receiver application in chromecast we are getting a problem as :
[goog.net.WebSocket] The WebSocket disconnected unexpectedly: undefined
cast_receiver_framework.js:507 WebSocket connection to 'ws://localhost:8008/v2/ipc' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
Our receiver has simple code as in example provided by CAF receiver in chromecast documentation:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const playbackConfig = new cast.framework.PlaybackConfig();
// Customize the license url for playback
playbackConfig.licenseUrl = 'https://wv-keyos.licensekeyserver.com/';
playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
playbackConfig.licenseRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
requestInfo.headers = {
'customdata': '<customdata>'
};
};
context.getPlayerManager().setMediaPlaybackInfoHandler((loadRequest, playbackConfig) => {
if (loadRequest.media.customData && loadRequest.media.customData.licenseUrl) {
playbackConfig.licenseUrl = loadRequest.media.customData.licenseUrl;
}
return playbackConfig;
});
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
if(request.media.contentType == 'video/mp4') {
return resolve(request);
}
// Fetch content repository by requested contentId
makeRequest('GET', 'https://tse-summit.firebaseio.com/content.json?orderBy=%22$key%22&equalTo=%22'+ request.media.contentId + '%22')
.then(function (data) {
var item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error('MyAPP.LOG', 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentId = item.stream.hls;
request.media.contentType = 'application/x-mpegurl';
castDebugLogger.warn('MyAPP.LOG', 'Playable URL:', request.media.contentId);
// Add metadata
var metadata = new cast.framework.messages.MovieMediaMetadata();
metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
resolve(request);
}
});
});
});
/** Debug Logger **/
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
// Enable debug logger and show a warning on receiver
// NOTE: make sure it is disabled on production
castDebugLogger.setEnabled(false);
playerManager.addEventListener(
cast.framework.events.category.CORE,
event => {
castDebugLogger.info('ANALYTICS', 'CORE EVENT:', event);
});
// Set verbosity level for custom tags
castDebugLogger.loggerLevelByTags = {
'MyAPP.LOG': cast.framework.LoggerLevel.WARNING,
'ANALYTICS': cast.framework.LoggerLevel.INFO,
};
/** Optimizing for smart displays **/
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
const touchControls = cast.framework.ui.Controls.getInstance();
let browseItems = getBrwoseItems();
function getBrwoseItems() {
let data = '"video": { \
<Encrypted Video>
}, \
"title": "Big Buck Bunny" \
}';
let browseItems = [];
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio =
cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
// Media browse
touchControls.setBrowseContent(browseContent);
});
context.start({playbackConfig: playbackConfig});
This code takes the input from sender but even if sender has application ID it shows the same message.
Can someone please explain to me why i'm getting this warning Warning: a promise was created in a handler but was not returned from it when I execute the following code:
cache['deviceSlave'].getBySystemId(systemId).then(function(slavesMapping) {
// do other stuff
}).catch(function(err) {
// throw error
});
Here is the rest of the code:
var Promise = require('bluebird');
var _ = require('lodash');
var Redis = require('ioredis');
var config = require('/libs/config');
var redis = new Redis({
port: config.get('redis:port'),
host: config.get('redis:host'),
password: config.get('redis:key'),
db: 0
});
var self = this;
module.exports.getBySystemId = function(systemId) {
return new Promise(function(resolve, reject) {
var systemIds = [systemId];
self.getBySystemIds(systemIds).then(function(result) {
return resolve(_.values(result)[0]);
}).catch(function(err) {
return reject(err);
});
});
};
module.exports.getBySystemIds = function(systemIds) {
return new Promise(function(resolve, reject) {
var pipeline = redis.pipeline();
_.each(systemIds, function(systemId) {
var cacheKey = 'device_slaves:' + systemId.replace(/:/g, '');
// get through pipeline for fast retrieval
pipeline.get(cacheKey);
});
pipeline.exec(function(err, results) {
if (err) return reject(err);
else {
var mapping = {};
_.each(systemIds, function(systemId, index) {
var key = systemId;
var slaves = JSON.parse(results[index][1]);
mapping[key] = slaves;
});
return resolve(mapping);
}
});
});
};
I'm using the following libraries: ioredis & bluebird.
The code executes fine and everything just works good! I just dont like the fact I get an warning which I can not solve!
Bluebird is warning you against explicit construction here. Here is how you should write the above code:
module.exports.getBySystemId = function(systemId) {
return self.getBySystemIds([systemId]).then(result => _.values(result)[0]);
};
There is no need to wrap the promise - as promises chain :)
Currently have IO sockets with laravel broadcasting with redis working perfectly. Until I then set up an SSL cert on the domain.
I have redis-server running on port 3001.
Then there is a socket.js set to listen to 3000.
My JS on the page I listen via io('//{{ $listen }}:3000').
Any guidance would be great on how to get this working over https. Would I just use 443 as the port?
Thanks.
My socket.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('notifications', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
First, setup your serverOptions object:
var serverOptions = {
port: 3000,
host: 127.0.0.1, //address to your site
key: '/etc/nginx/ssl/your_site/server.key', //Or whatever the path to your SSL is
cert: '/etc/nginx/ssl/your_site/server.crt',
NPNProtocols: ['http/2.0', 'spdy', 'http/1.1', 'http/1.0']
}
For the NPNProtocols, you may not care for all of them, but they're provided for reference.
Now just create the server:
var app = require('https').createServer(serverOptions),
io = require('socket.io')(app);
This should be pretty plug and play into your source at his point.\
As a side note your stuff is completely wide open and anyone can listen on your web socket, so nothing should be sent that is private through here. If you need to make your data private, then you're going to need 1 of two things;
Something like JWT-Auth Token
Something custom that interface with the Redis queue:
Here's an example of the latter:
var SECRET_KEY = '<YOUR_LARAVEL_SECRET_KEY>';
var laravel_session_parser = {
ord: function (string) {
return string.charCodeAt(0);
},
decryptSession: function (cookie, secret) {
if (cookie) {
var session_cookie = JSON.parse(new Buffer(cookie, 'base64'));
var iv = new Buffer(session_cookie.iv, 'base64');
var value = new Buffer(session_cookie.value, 'base64');
var rijCbc = new mcrypt.MCrypt('rijndael-128', 'cbc');
rijCbc.open(secret, iv);
var decrypted = rijCbc.decrypt(value).toString();
var len = decrypted.length - 1;
var pad = laravel_session_parser.ord(decrypted.charAt(len));
return phpunserialize.unserialize(decrypted.substr(0, decrypted.length - pad));
}
return null;
},
getUidFromObj: function (obj, pattern) {
var regexp = /login_web_([a-zA-Z0-9]+)/gi;
if (pattern) {
regexp = pattern;
}
var u_id = null;
for (var key in obj) {
var matches_array = key.match(regexp);
if (matches_array && matches_array.length > 0) {
u_id = obj[matches_array[0]];
return u_id;
}
}
return u_id;
},
getRedisSession: function (s_id, cb) {
var _sessionId = 'laravel:' + s_id;
client.get(_sessionId, function (err, session) {
if (err) {
cb && cb(err);
return;
}
cb && cb(null, session);
});
},
getSessionId: function (session, _callback) {
var u_id = null,
err = null;
try {
var laravelSession = phpunserialize.unserialize(phpunserialize.unserialize(session));
u_id = laravel_session_parser.getUidFromObj(laravelSession);
} catch (err) {
_callback(err, null);
}
_callback(err, u_id);
},
ready: function (socket, _callback) {
if (typeof socket.handshake.headers.cookie === 'string') {
var cookies = cookie.parse(socket.handshake.headers.cookie);
var laravel_session = cookies.laravel_session;
var session_id = laravel_session_parser.decryptSession(laravel_session, SECRET_KEY);
laravel_session_parser.getRedisSession(session_id, function (err, session) {
if (!err && session) {
laravel_session_parser.getSessionId(session, function (err, user_id) {
if (user_id) {
_callback(null, session_id, user_id, laravel_session)
} else {
_callback(new Error('Authentication error'), null);
}
});
} else {
_callback(new Error('Authentication error'), null);
}
});
}
}
};
Now you can just have IO get an instance of the individuals session when they establish a connection to socket.io
io.on('connection', function (socket) {
laravel_session_parser.ready(socket, function(err, session_id, user_id, laravel_session) {
//log out the variables above to see what they provide
});
});
Note, I prefer to use dotenv in NodeJS to share environment variables between Laravel and Node.
Then you can do process.env.APP_KEY and you don't need to worry about sharing variables.
Also of note, that script above is not complete and is not production ready, it's just meant to be used as an example.
Using ionic,
I am trying to create an image blob from URI and have tried several codes but failed.
Here is where I implement the imagepicker in ionic:
$cordovaImagePicker.getPictures(options)
.then(function (results) {
console.log(results[0]);
var datablob = $scope.dataURItoBlob(results[0]);
technique 1 (create the blob):
$scope.dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
return new Blob([new Uint8Array(array)], {
type: mimeString
});
}
technique 2 (create the blob):
$scope.dataURItoBlob = function(dataURI) {
var arr = dataURI.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
Both techniques does not work. Please help! thank you very much.
$cordovaImagePicker.getPictures(options)
.then(function (results) {
console.log(results[0]);
dataURItoBlob(results[0], function(url){
var datablob = url;
}, function(error){
console.error(error);
})
})
function dataURItoBlob(path, cb, error) {
resolveLocalFileSystemURL(path, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function () {
if (typeof cb === 'function') {
cb(this.result)
}
};
reader.readAsDataURL(file);
}, function (err) {
if (typeof error === 'function') {
error(err)
}
});
});
}
Needs to cordova-plugin-file