I am currently connecting to an external XMPP server (not mine). Since I couldn't find any XMPP PHP client which suits my needs, I have developed my own simple client (XMPP PHP). The client opens a socket connection to the server and that is where the XML exchange happens, and that part works well.
The main reason for developing this package was to integrate it within a corporate app. I have done so and can successfully send messages back and forth.
Even though my end goal is to have an open websocket connection, currently the program works by polling the server in 2s interval (I am using a simple 1on1 communication, no chat rooms or similar):
receiveMessages: function () {
this.poll = setInterval(function () {
Ext.Ajax.request({
url : 'index.php',
method : 'post',
params : {
method: 'receiveMessages',
},
scope : this,
callback: function (options, success, response) {
...
}
});
}, this.pollTimer);
}
And on the PHP side:
public function receiveMessages()
{
$messages = $this->client->getMessages();
if ($messages) {
foreach ($messages as $message) {
$message = $this->xml2array($message);
$conversation = $this->conversationExists($message['#attributes']['from']);
if ($conversation == null) {
$preparedConversation = array(
...
);
$conversation = $this->_save($preparedConversation ...);
}
$message = array(
...
);
$response = $this->_save($message ...);
return array(
'success' => true,
'response' => $response,
);
}
}
}
Upon success, this method updates frontend with the received message, as well as saves the message to the DB. DB is organized in a way that one User can have many Conversations and one Conversation can have many Messages.
What I fail to understand though is how should everything be structured in order to function like some of the real chat clients (Facebook or other messengers), because this way I can't get the "concurrency" I want. If I log in with my account on 2 different places, each of them will poll the server every 2s, and it is basically a race condition, first one to get the message will display it.
If I think about it, one way to do it properly would be to implement websockets to server, and have frontend wait for DB changes, however I think this may create much read overhead on DB. Can someone give me some advice on how to do this?
Related
I am developing a project, a wordpress plugin. And I have to do instant transactions, so I wanted to use websocket instead of ajax.I run node.js with socket.io on my server server now everything goes well. But how do I send the data coming to the node.js server to php? I ran an ajax query for this, on the node.js side, how correct is this usage. I also tried some derivatives such as elephant.io and I couldn't send data to socket.io with php.
I've been searching for almost 2 days, but the sources I found are always old and I could not come to a conclusion so I decided to ask here.
How do I transfer the data sent from the client to node.js to php and get the returned data.
How do I send data from PHP to socket.io or socket.io to PHP?
Is it logical to send the data sent from the client via websocket to the php page with ajax in node.js?
In fact, the 3 questions I ask are in the same place, except for the basic differences, can you help me with this?
Yes, I can now send data to the client with a php page. But how do I capture the data from the client here.
require __DIR__ . '/vendor/autoload.php';
use ElephantIO\Client;
use ElephantIO\Engine\SocketIO\Version2X;
$client = new Client(new Version2X('http://localhost:3000'));
$client->initialize();
$client->emit('server_way', ['foo' => 'bar']);
$client->close();
if ( isset( $_GET['action'] ) ) {
echo $_GET['action'];
}
const ajax_url = 'http://localhost/projeler/bp-instant-message-socket-io-core/socket.php';
const http = require('http').createServer();
const io = require('socket.io')(http,{
cors: {
origin: "http://localhost",
methods: ["GET", "POST"]
}
});
var $ = require('jquery')(require('jsdom-no-contextify').jsdom().parentWindow);
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
$.support.cors = true;
$.ajaxSettings.xhr = function () {
return new XMLHttpRequest;
}
io.on('connection', (socket) => {
console.log("biri bağlandı");
socket.on('server_way', (data) => {
console.log(data);
io.emit('client_way',data);
});
socket.on('disconnect',function(){
console.log("biri ayrıldı");
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
Hello I'm using Ionic framework and express to comunicate between my application, a server API, and a javascript game. The game sends some information to the API using XMLHttpRequest and post and my application retrives this information using Http from angular/http.
The post part works well and I'm able to send information to the server, but I'm struggling with the get part . The get method is called every time that my page is refreshed but at this time the game hasn't sent the data, and when it does the get method isn't called again, so I never get the data from the server.
the game send info like that :
function sendFriendToInvite(friend, callback) {
var req = new XMLHttpRequest();
req.open('POST', 'http://localhost:3001/sendInvite');
req.setRequestHeader('Content-Type', 'application/json');
req.send(JSON.stringify({friend: friend}));
req.addEventListener('load', () => {
console.log(req.responseText);
var results = JSON.parse(req.responseText);
//if(results.error) return console.log(results.error);
if(callback) callback(results);
});
req.addEventListener('error', (e) => {
console.log('an error occured');
console.log(e);
});
}
the server get and post method are :
var friendToInvite;
/**Send from the game**/
api.post('/sendInvite', function(req, res) {
console.log("posts! " + req.body.friend);
friendToInvite = req.body.friend;
res.send({message: 'friend reçu'})
});
/**retrive by the application **/
api.get('/sendInvite', function(req, res) {
console.log("get friend to invite");
//here I need friendToInvite be initialised by the post method before sending the response
res.json({friend: friendToInvite});
});
the application get info like that :
this.http.get('http://localhost:3001/sendInvite').pipe(
map(res => res.json())
).subscribe(response => {
console.log('GET Response:', response);
});
I whant the application retrive data when the game send the data.
I think you should use sockets to communicate between the server and your app.
Another simpler and less efficient option may be to do the GET in an interval function so you can call to the server every X seconds (say 1 minute, for example) to update the data. This implies that your app is constantly calling to the server and I strongly discourage it.
EDIT:
I suggested using sockets because I have used this method occasionally to communicate between server and app but it would also be a good option, if you only need communication from the server to the app and not vice versa, to use push notifications.
I created an observable for my websocket connection using WebSocketSubject from rxjs. So far so good the server-client communication is working. Now the thing is: I can't distinguish between the origins of the message in my client. I send messages by calling next() on the subject. All subscriptions on the client get those messages too. How can I send messages only to the server instead?
The implementation mainly stems from this article: https://medium.com/factory-mind/angular-websocket-node-31f421c753ff
My code:
socket$: WebSocketSubject<any>;
constructor() {
this.socket$ = WebSocketSubject.create(SOCKET_URL);
this.socket$.subscribe(
(message) => console.log('<-- ' + message),
(err) => console.error('Error on WebSocket:', err),
() => console.warn('Completed!')
);
}
send(message: SocketMessage) {
const tmp: any = {};
tmp.type = message.type;
tmp.payload = message.payload;
// This will be received by the server but also by client subscriptions = bad
this.socket$.next(JSON.stringify(tmp));
}
I found a solution trying to have your described behavior :
RxJS6's WebSocket's documentation states that
Calling next does not affect subscribers of WebSocketSubject - they have no information that something was sent to the server (unless of course the server responds somehow to a message).
Thus, by using RxJS 6 instead of RxJS 5 you should not have the described behavior.
I'm trying to make a chat system where anyone can go into the chat and send a message. The messages are stored in a MySQL database and my code looks like this at the moment ...
<script>
$('input[type=text]').on('keydown', function(e) {
if(e.which == 13) {
e.preventDefault();
$.ajax({
url: "php/chat.class.php",
data: { steamid: "<?php echo $steamprofile['steamid']?>", message: document.getElementById("chatMessage").value },
type: "GET",
context: document.body
}).done(function() {
alert("Message sent");
// This is when the chat should update for everyone
}).error(function() {
document.getElementById('chat-box').innerHTML += '<span class="text-muted"><i>Could not send chat message at this time.</i></span>';
});
}
});
Basically, it inserts a new row into the MySQL table once you press enter.
As it is a chat for everyone, I need the chat to update for every user when anyone sends a message.
I know how to display all the messages and who sent them, but I need it to update whenever someone sends a message, for everyone.
I've done research but I can't find anything useful unfortunately and now I'm clueless.
I've thought of updating the chat every x seconds, but I want to make the chat as smooth and fast as possible and wondering what the best solution would be.
Have a good day
So that is a read operation, and hence what you are trying is a write operation. Either you can do a continuous lookup to the server with a interval/timeout/ or initiate a rest call when last call was finished (success/error/timeout whatever). but better approach for this will be initiating a WebSocket Client and create and set up WebSocket Server in your backend and design it properly, so if it get any message from any client it will send that to all other client or something optimizer/ or something in schedule
Consider using a realtime database like Firebase https://firebase.google.com/docs/database/web/start and on your client side you can listen to messages being added using something like:
commentsRef.on('child_added', function(data) {
addCommentElement(postElement, data.key, data.val().text, data.val().author);
});
With firebase you can create a serverless chat application.
I need to be able to get realtime notifications once a PHP script has finished, Im using jQuery, PHP, AJAX, nodeJS.
I send some stuff via AJAX to the PHP script, I need to be able to notify the user when this script starts (simple) but I need to be able to use nodeJS to notify when it’s finished.
AJAX Script
$(document).ready(function($) {
$('.rules-table').on('click', '.runRule', function(event) {
event.preventDefault();
/* Act on the event */
var ruleID = $(this).parents('tr').attr('id');
$.ajax({
url: '/ajax/run-rule.php',
type: 'POST',
dataType: 'json',
data: {
ruleID: ruleID
},
})
.done(function(data) {
console.log(data);
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
});
});
Sends to a PHP script which does a load of processing (could take a while)
so I need to access NodeJS from here to notify the user it's running, then notify when it's finished. How can i?
When Ajax makes request to php at the starting store sessionid and request id to any database like redis and Use NodeJs with Socket.io for sending real time notifications. In your PHP code create a function like below where $data is the information and $requestId is the id of the ajax request. And in your nodeJs code get the session id regarding that requestId and emit the message to be diplayed.
public static function sendSocketMessage($data, $requestId) {
$url = 'http://' . url . ':3000/publish?salt=<some_salt>';
$curl = new \skeeks\yii2\curl\Curl();
$curl->setOption(CURLOPT_POSTFIELDS, json_encode(array(
'id' => $requestId,
'message' => $data,
)));
$curl->setOption(CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
));
return $curl->post($url);
}
The best way to go is to implement a messaging service in nodeJS. Basicaly a messaging service is a service where client can subscribe to some sort of events. Also another client can push events to the service (so this event can be delivered to subscribed client).
It's quite standard these days. Most online messaging services works that way (Pusher, Pubnub, etc) so by implementing this model in your node app, you'll be able later to outsource the realtime part to a 3rd-party service.
The delivering can be done using socket.io (which already implement a subscribing and room pattern). The publishing can be any endpoint (a socket.io special message, a REST endpoint, whatever express can handle out of the box).