Kindly Note: I know this might be a possible duplicate of other questions but i'd like help with my code!!
I'm trying to build a chat feature for my social network..I've used node.js and socket.io ...The prob with this code is that, the message is being delivered to every connected user instead of just the targeted to_user...The source of this code is from thenewboston tutorials...
I've built it as of now like this:
client.php
<div class="chat" hidden>
<textarea class="chat-name"><?php echo escape($data->username); ?></textarea>
<div class="chat-messages">
<?php
$chtrndr = $cht->renderchats(escape($data->id));
foreach ($chtrndr as $chtrndrs) {
echo '<div>' . $chtrndrs['m_from'] . ': ' . $chtrndrs['m_text'] . '</div><br>';
}
?>
</div>
<textarea class="chat-textarea" placeholder="Type your message"></textarea>
<div class="chat-status">Status:<span>Idle</span></div>
</div>
<!-- <script src="/socket.io/socket.io.js"></script> -->
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script src="server.js"></script>
<script>
(function(){
var getNode = function(s) {
return document.querySelector(s);
},
//get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat-textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s) {
status.textContent = s;
if(s!==statusDefault)
{
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
},3000);
}
};
setStatus('testing');
try {
var socket = io.connect('http://127.0.0.1:8080');
}
catch(e)
{
//set status to warn user
}
if(socket!==undefined)
{
//listen for output
socket.on('output',function(data){
if(data.length)
{
//loop through results
for(var x=0;x<data.length;x=x+1)
{
var message = document.createElement('div');
message.setAttribute('class','chat-message');
message.textContent = data[x].m_from + ': ' + data[x].m_text;
//append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//listen for a status
socket.on('status',function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true)
{
textarea.value = '';
}
});
//listen for keydown
textarea.addEventListener('keydown',function(event){
var self = this,
fname = <?php echo escape($_SESSION['user']); ?>,
tname = <?php echo $data->id; ?>;
if(event.which === 13 && event.shiftKey === false) {
socket.emit('input', {m_from:fname, m_to:tname, m_text:self.value});
event.preventDefault();
}
});
}
})();
</script>
And this is the server file:
SERVER.js
var client = require('socket.io').listen(8080).sockets;
var express = require('express');
var app = express();
var mysql = require('mysql');
var path = require('path');
var dbconn = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'test'
});
app.use(express.static(path.resolve(__dirname, './css/')));
app.get('/',function(req,res){
res.sendFile(__dirname + '/index.html');
});
dbconn.connect(function(err){
if(err){
console.log('Database connection error');
}else{
console.log('Database connection successful');
}
client.on('connection',function(socket){
console.log('Data received from Db');
sendStatus = function(s){
socket.emit('status',s);
};
//wait for input
socket.on('input',function(data){
var fname = data.m_from,
tname = data.m_to,
m_text = data.m_text,
whitespacePattern = /^\s*$/;
if(whitespacePattern.test(m_text))
{
sendStatus('message is required');
}
else
{
var record = { m_from: fname, m_to:tname, m_text: m_text };
dbconn.query('INSERT INTO messages SET ?', record, function(err,res){
if(err) throw err;
client.emit('output',[data]);
sendStatus({
message: "message sent",
clear: true
});
});
}
});
});
});
i wud like to add the following functionality:
*(a)*Since it is a social network, it shud be capable of serving private chats, betn 2 logged in users...
(b) The messages shud be received by the receiver after he logs back in at a later time..
I've combed many pages on google n SO already and heard that rooms are my go-to. But being a noob in nodejs, idk how to implement the rooms to make private messaging possible...
If any1 cud help me code it or even set me on the right path, frm where i can learn to code in node.js with easy tutorials for beginners, it wud b a really gr8 help!! Thanx in advance!
Look it should be like every user in your application should have unique id
LOGIC
1.you have to emit the event from your backend(server side) on output_userId
Your frontEnd (client side) should listen to the socket event on output_userId
what this will do is like you are emitting the message for the specific user from server side and every user will be listening on output_userId which is their specific id. where userId is there unique id of the project.
example:
we have 3 users
1,2,3
now if user 1 is sending message to user 2
your events should be like
Server Side
Socket.emit(output_1)
client side
every client side user should listen to their output_userid
for user 1 it should be output_1
for user 2 it should be output_2
for user 3 it should be output_3
Related
I have a div section. I want to reload this section every 5 seconds. How do I do this. Here is my code:
<script>
$("#send_parent_general_chat").submit(function()
{
var rec = $("#data").val();
var msg = $("#msg").val();
var dataString = 'rec='+ rec + '&msg='+ msg;
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>" + "Client/send_general_parent_chat_msg/<?php echo $per_job->id;?>",
data: dataString,
cache: false,
success: function(result){
$('#display_general_msg').html(result);
$('#send_parent_general_chat')[0].reset(); //form reset
}
});
return false;
});
</script>
<script>
$(document).ready(function(){
setInterval(function(){
// alert("===111==");
$("#display_general_msg").load('<?php echo base_url(); ?>" + "Client/refresh_general_parent_chat_msg/<?php echo $per_job->id;?>')
}, 5000);
});
</script>
I have created one more controller for refreshing the div I have used the time interval function but it is not loading, it shows this error:
Access forbidden!
You don't have permission to access the requested object. It is either read-protected or not readable by the server.
If you think this is a server error, please contact the webmaster.
Error 403
I need to refresh only the div content not the whole page.
How do I achieve this?
You can Use :
setTimeout(function()
{
Your_Function(); //this will send request again and again;
}, 5000);
Replace Your_Function with your Function Name.
Hope this will help !!
Below is an example which will update the contents in every 5 seconds using php websockets. This is a simple example, but you can use it to modify to fit for your application needs. You don't need the timeout functions on the client side here we use server sleep
Install the Workerman socket library
composer require workerman/workerman
The client side code
<!DOCTYPE HTML>
<html>
<head>
<script type = "text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:2346");
ws.onopen = function() {
// Web Socket is connected, send data using send()
ws.send("Message to send");
//alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
//alert("Message is received..." + received_msg);
document.getElementById("demo").innerHTML = "Timestamp is updated every 5 sec " +received_msg;
};
ws.onclose = function() {
// websocket is closed.
alert("Connection is closed...");
};
} else {
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id = "sse">
Run WebSocket
</div>
<div id="demo" style="font-size: 64px; color: red;"></div>
</body>
</html>
The Server side code
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 4 processes
$ws_worker->count = 4;
// Emitted when new connection come
$ws_worker->onConnect = function($connection)
{
echo "New connection\n";
};
// Emitted when data received
$ws_worker->onMessage = function($connection, $data)
{
// Send hello $data
while(true) {
$connection->send(time());
sleep(5); //Sleep for 5 seconds to send another message.
}
};
// Emitted when connection closed
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// Run worker
Worker::runAll();
The backend service can be started with the following command from the terminal or you can autostart on boot if you want.
$php index.php start
Here index.php is our backendnd file name.
Just start the service and load the page then you can see the timestamp is updated every 5 seconds which comes from the server side. This is a working example tested on my local machine. Try and let me know if you need any other help.
The output
you can also try below one:
setInterval(function(){
loadlink() // this will run after every 5 seconds
}, 5000);
setInterval approach will be more accurate than the setTimeout approach
// or
$(function(){ // document.ready function...
setTimeout(function(){
$('form').submit();
},5000);
});
I have PHP site with MySql data base
I just added automatic save for a text area
and one of the users received the following error:
Too many connections in ...Unable to connect to database
maybe I have to change my ajax auto save:
bkLib.onDomLoaded(function(){
var myEditor = new nicEditor({iconsPath : 'include/nicEdit/nicEditorIcons.gif'}).panelInstance('area1');
auto_save_func(myEditor);
});
function auto_save_func(myEditor)
{
draft_content=myEditor.instanceById('area1').getContent();
int_id='<?=$_GET[interview_id]?>';
$.post("ajax_for_auto_save_interview.php", { interview_id: int_id,content:draft_content},
function(data){ });
setTimeout( function() { auto_sav_func(myEditor); }, 100);
}
in the page "ajax_for_auto_save_interview.php" I`m including the connection to the DB.
First thing is you should close your mysql connection every time you open it after your usage.
You can have a javascript variable to check whether an AJAX call is already issued and is it finished or not. Only if it is finished, you can re-issue new call
Like this:
var isAjaxStarted = 0;
bkLib.onDomLoaded(function(){
var myEditor = new nicEditor({iconsPath : 'include/nicEdit/nicEditorIcons.gif'}).panelInstance('area1');
if(isAjaxStarted == 0)
auto_save_func(myEditor);
});
function auto_save_func(myEditor)
{
isAjaxStarted = 1;
draft_content=myEditor.instanceById('area1').getContent();
int_id='<?=$_GET[interview_id]?>';
$.post("ajax_for_auto_save_interview.php", { interview_id: int_id,content:draft_content},
function(data){ isAjaxStarted = 0; });
setTimeout( function() { auto_sav_func(myEditor); }, 100);
}
maybe I am writing late you help in place it? thank you very much
<script type="text/javascript">
bkLib.onDomLoaded(function() {
var myNicEditor = new nicEditor({buttonList : ['bold','italic','underline','strikethrough','left','center','right','justify',/*'ol','ul',*/'forecolor',/*'fontSize','fontFamily',*//*'fontFormat',*//*'indent','outdent',*/'image','upload','link','unlink'/*,'bgcolor'*/,'hr','removeformat', 'youTube'/*,'subscript','superscript'*/],/*fullPanel : true,*/
iconsPath : '<? echo "".$IndirizzoPagina."".$IndirizzoCartella."";?>default/image/EditorDiTesto/nicEditorIcons.gif'});
myNicEditor.setPanel('myNicPanel'); //PANNELLO DI CONTROLLO
myNicEditor.addInstance('titolo'); //TITOLO
myNicEditor.addInstance('contenuto'); //CONTENUTO
});
<textarea name='contenuto' id='contenuto' class='box2'>".$ContenutoNotizia."</textarea>"
i used this code http://nicedit.com/
I am working on a basic authentication mobile app for iPhone using:
Titanium v. 3.23
XAMPP as my local server and PHP
MySQL as local database
The app I am working on is based off the following tutorial:
http://code.tutsplus.com/tutorials/titanium-user-authentication-part-1--mobile-3728
I was able to get the code up and running from the tutorial with no problem, the app allowed me to post a username/password key to my local database, login with the key, and have the information displayed on my main window.
I began to manipulate the code to reflect more of what I am attempting to build, a single window based app (not tab based like in the tutorial) that would allow me to create a username/password key, login to a main window, and on that main window have my information displayed back to me.
I have successfully been able to modify the code to allow me to create a new username/password into my local database, as well as have the app verify if the username/password match upon login. However, when I login to my main screen, it shows that my username and password are "undefined". To check the error, I entered the same user/pass in the project currently holding the working code and it is visible. So I know my current PHP and database are all working correctly.
Currently, my app.js is:
setTimeout (function() {
var login;
login = require ('login');
login.LogIn();
var mainWin = Titanium.UI.createWindow();
Ti.App.addEventListener('grantEntrance', function(event){
mainWin.title = 'Welcome ' + event.name;
mainWin.url = 'main.js';
mainWin.name = event.name;
mainWin.email = event.email;
});
}, 2000);
The setTimeout function is to eventually be a splash screen which I added independent from the tutorial above. I also changed the "main" items to reflect my mainWin, rather than the "main" as indicated in the tutorial.
Currently, my login.js is:
function LogIn(){
var loginWin = Ti.UI.createWindow({
backgroundColor:'white'
});
var username = Titanium.UI.createTextField({
color:'#336699',
top:10,
left:10,
width:300,
height:40,
hintText:'Username',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
loginWin.add(username);
var password = Titanium.UI.createTextField({
color:'#336699',
top:60,
left:10,
width:300,
height:40,
hintText:'Password',
passwordMask:true,
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
loginWin.add(password);
var loginBtn = Titanium.UI.createButton({
title:'Login',
top:110,
width:90,
height:35,
borderRadius:1,
font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
loginWin.add(loginBtn);
var createLabel = Titanium.UI.createLabel({
text:'Create Profile',
bottom: 25,
left:25
});
loginWin.add(createLabel);
var indicatorWin = Ti.UI.createView({
width: 320,
height: 480,
backgroundColor: '#000000',
opacity: 0.5
});
var acctInd = Ti.UI.createActivityIndicator({
height:50,
width:50,
style: Titanium.UI.createActivityIndicatorStyle.Plain,
top:250,
left:130
});
var actLabel = Titanium.UI.createLabel({
text: 'Checking Login Details',
color: '#FFFFFF',
left:70,
top:200,
height:50
});
indicatorWin.hide();
acctInd.hide();
actLabel.hide():
loginWin.add(indicatorWin);
indicatorWin.add(acctInd);
indicatorWin.add(actLabel);
var loginReq = Titanium.Network.createHTTPClient();
loginReq.onload = function()
{
var json = this.responseText;
var response = JSON.parse(json);
if (response.logged == true)
{
username.blur();
password.blur();
Ti.App.fireEvent('grantEntrance', {
name:response.name,
email:response.email
});
loginWin.close();
var main;
main = require ('main');
main.MainM();
}
else
{
alert(response.message);
}
};
loginBtn.addEventListener('click',function(e)
{
if (username.value != '' && password.value != '')
{
loginReq.open("POST","http://localhost/Tuts/post_auth.php");
var params = {
username: username.value,
password: Ti.Utils.md5HexDigest(password.value)
};
loginReq.send(params);
indicatorWin.show();
acctInd.show();
actLabel.show();
}
else
{
alert("Username/Password are required");
}
});
createLabel.addEventListener('click', function(e) {
var ProfileWin, ProfileInc;
ProfileInc = require ('createProfile');
ProfileWin = new ProfileInc.CreateP();
ProfileWin.open();
});
loginWin.open();
return ;loginWin;
}
exports.LogIn=LogIn;
Currently, my main.js is:
function MainM(){
var mainWin = Ti.UI.createWindow({
backgroundColor:'white'
});
var msg = Titanium.UI.createLabel({
text:"\n\nYour email is:\n" + mainWin.email + "\n\nyour name is:\n" + mainWin.name,
top:10,
left:10,
width:300,
height:'auto'
});
mainWin.add(msg);
mainWin.open();
return ;mainWin;
}
exports.MainM=MainM;
As you can see I haven't changed much, if anything, to the actual database section of the app. Which is why I am confused that it isn't working. The only research I have found indicated that there might be a problem with an asynchronous request and heard that by using a setTimeout function i might be able to get around my error. I have attempted to insert the function in a few places however the error still persists.
Sorry so long, I have been working on this for a month and I wanted to be as detailed as possible.
Thanks for the help!
In your code, main screen is a new Window, which does not have access to the variables email and name.
What you can do to fetch the values in the min win is either Save them in Properties and use them, or modify your main.js .
I've heard that nodejs is the best choice for creating real-time chat application. So I decide to try one.
//on server side
//create nodejs server
var http = require('http');
var chatApp = http.createServer(function (request, response) {
//create an html chat form listened by this nodejs server
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<script src="http://localhost/nodejs/app/socket.io.js"></script><script src="http://localhost/nodejs/app/chat.client.js"></script><input type="text" id="message_input"><div id="chatlog"></div>');
response.end();
}).listen(8000);
//create websocket protocol via socket.io
var io = require('socket.io').listen(chatApp);
//send data to client
io.sockets.on('connection', function(socket) {
socket.on('message_to_server', function(data) {
io.sockets.emit("message_to_client",{ message: data["message"] });
});
});
//on client side
//get data from server response
var socketio = io.connect();
socketio.on("message_to_client", function(data) {
document.getElementById("chatlog").innerHTML = ("<hr/>" +
data['message'] + document.getElementById("chatlog").innerHTML);
});
//submit and send data to server via enter key
document.onkeydown = function(e){
var keyCode = (window.event) ? e.which : e.keyCode;
if(keyCode == 13){
var msg = document.getElementById("message_input").value;
socketio.emit("message_to_server", { message : msg});
document.getElementById("message_input").value = '';
}
};
Everything seems ok but php webapp intergration. How could I make it work as a part of a php web page?
As mentioned in my original comment, you can let your PHP application continue doing what it has been doing all along and just use NodeJS for handling web socket connections (via the socket.io) library. Here is an example of a simplified structure you could use:
Your chat.php page or Chat controller:
<?php
// Handle /chat route
// Perform any authentication with your database
// Render template
?>
<!-- The following HTML is rendered -->
<html>
<head>
...
<script src="http://localhost/nodejs/app/socket.io.js"></script>
<script src="http://localhost/nodejs/app/chat.client.js"></script>
</head>
<body>
...
<input type="text" id="message_input">
<div id="chatlog"></div>
...
<script>
var socketio = io.connect('http://localhost:8080');
socketio.on("message_to_client", function(data) {
document.getElementById("chatlog").innerHTML = ("<hr/>" +
data['message'] + document.getElementById("chatlog").innerHTML);
});
//submit and send data to server via enter key
document.onkeydown = function(e){
var keyCode = (window.event) ? e.which : e.keyCode;
if(keyCode == 13){
var msg = document.getElementById("message_input").value;
socketio.emit("message_to_server", { message : msg});
document.getElementById("message_input").value = '';
}
};
</script>
</body>
</html>
Your NodeJS application would look like the following. Note the lack of regular HTTP connection handling, which we now let PHP handle:
//create websocket protocol via socket.io
var io = require('socket.io').listen(8080);
//send data to client
io.sockets.on('connection', function(socket) {
socket.on('message_to_server', function(data) {
io.sockets.emit("message_to_client",{ message: data["message"] });
});
});
And that is the base you would use. As mentioned before in my comment, it is possible to extend this to add database-backed authentication mechanisms to the NodeJS portion of the server.
Trying to create an AJAX IM for my site...
need to load the part of page when row is inserted into mysql DB ... can anybody help me with this.. thanks in advance
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
var waittime=2000;
var intUpdate = null;
function verifDB(){
$.ajax({
type: "POST",
url: "verifdb.php",
success: function(msg){
alert(msg),;
}
});
intUpdate = setTimeout("verifDB()", waittime);
}
verifDB();
</script>
verifdb.php file is queried every 2000 ms to check on the database
you can put your file in requette verifdb.php
and you will have the answer in the variable msg
Client Side
For assyncronous requests on the client side you can use JQuery or plain Javascript XMLHTTPRequest
Server Side
I know you've specified PHP but I would recommend you to check how google channels work and make a similar implementation in PHP.
Since checking having multiple users checking for updates on the database, I would recommend you to use memcache.
Something like:
$script_called_time = time();
while($memcache->get('last_message') < $script_called_time){
usleep(100);
}
$result = $database->query("SELECT * FROM `messages` WHERE `date` > " . $script_called_time . "'");
...
This way the connection will be established and the user will receive a response when there's any...
(function() {
var chat = {
messageToSend: "",
messageResponses: [
"I Love You",
"I Wants to Kiss You.",
'Hug Me!"',
"Lets Sleep Together",
"Lets go for a date",
"Will you be physical with me?"
],
init: function() {
this.cacheDOM();
this.bindEvents();
this.render();
},
cacheDOM: function() {
this.$chatHistory = $(".chat-history");
this.$button = $("button");
this.$textarea = $("#message-to-send");
this.$chatHistoryList = this.$chatHistory.find("ul");
},
bindEvents: function() {
this.$button.on("click", this.addMessage.bind(this));
this.$textarea.on("keyup", this.addMessageEnter.bind(this));
},
render: function() {
this.scrollToBottom();
if (this.messageToSend.trim() !== "") {
var template = Handlebars.compile($("#message-template").html());
var context = {
messageOutput: this.messageToSend,
time: this.getCurrentTime()
};
this.$chatHistoryList.append(template(context));
this.scrollToBottom();
this.$textarea.val("");
// responses
var templateResponse = Handlebars.compile(
$("#message-response-template").html()
);
var contextResponse = {
response: this.getRandomItem(this.messageResponses),
time: this.getCurrentTime()
};
setTimeout(
function() {
this.$chatHistoryList.append(templateResponse(contextResponse));
this.scrollToBottom();
}.bind(this),
1500
);
}
},
addMessage: function() {
this.messageToSend = this.$textarea.val();
this.render();
},
addMessageEnter: function(event) {
// enter was pressed
if (event.keyCode === 13) {
this.addMessage();
}
},
scrollToBottom: function() {
this.$chatHistory.scrollTop(this.$chatHistory[0].scrollHeight);
},
getCurrentTime: function() {
return new Date()
.toLocaleTimeString()
.replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, "$1$3");
},
getRandomItem: function(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
};
chat.init();
var searchFilter = {
options: { valueNames: ["name"] },
init: function() {
var userList = new List("people-list", this.options);
var noItems = $('<li id="no-items-found">No items found</li>');
userList.on("updated", function(list) {
if (list.matchingItems.length === 0) {
$(list.list).append(noItems);
} else {
noItems.detach();
}
});
}
};
searchFilter.init();
})();
Messenger Using Jquery And PHP
If you needs any help regarding this answer feel free to contact me at pachauriashokkumar[at]gmail[dot]com if you need complete code with css JS and HTML Drop me an email i will email the code to you
External Files are needed
https://code.jquery.com/jquery-3.4.1.js
https://cdn.jsdelivr.net/npm/handlebars#latest/dist/handlebars.js
https://raw.githubusercontent.com/javve/list.js/v1.5.0/dist/list.min.js
Messenger Using JQuery And PHP Demo Is Here Also Author of This Post on PenCode is available for clarification over email pachauriashokkumar[at]gmail[dot]com