I am trying to create a chat application using Socket and using Swoole as backend. I successfully create a connection to server-client but the issue I am facing now is that whenever I close terminal WebSocket is unable to connect.
Server code:-
<?php
//Create the websocket server object
$websocket_server = new swoole_websocket_server("MY_IP", 3000);
// Register function of the opening connection event
$websocket_server->on('open', function($websocket_server, $request){
var_dump($request->fd, $request->get, $request->server);
$websocket_server->push($request->fd, "Hello welcome\n");
});
// Register function of the receiving message event
$websocket_server->on('message', function($websocket_server, $frame){
echo "Message : {$frame->data}\n";
$websocket_server->push($frame->fd, "Server : {$frame->data}");
});
// Register function of the close event
$websocket_server->on('close', function($websocket_server, $fd){
echo "client_{$fd} is closed\n";
});
// Start the server
$websocket_server->start();
Client side Code:-
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script type="text/javascript">
var wsServer = 'ws://IP:3000';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
</script>
</body>
</html>
Everything is working fine the only issue is when we close terminal web socket id down.
I get the answer on Git. Please add below code in line
$websocket_server = new swoole_websocket_server("MY_IP", 3000);
$websocket_server->set([
'daemonize' => true,
]);
Related
I am testing botman chat. Followed documentation at https://botman.io/2.0/installation
Script open the chat widget at right bottom corner, but when I enter hello, it does not reply. Have tried multiple forums but not getting any solution.
Below is the script I am using
Installed botman
composer require botman/botman
Web Deriver
composer require botman/driver-web
index.php
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>COINS ChatBot</title>
<!-- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/assets/css/chat.min.css"> -->
</head>
<body>
<script>
// Feel free to change the settings on your need
var botmanWidget = {
frameEndpoint: '/chat.html',
chatServer: 'chat.php',
title: 'ChatBot',
introMessage: 'Hi and welcome to our chatbot how can i help you ?',
placeholderText: 'Ask Me Something',
mainColor: '#F28240',
bubbleBackground: '#F28240',
aboutText: '',
aboutLink: '',
bubbleAvatarUrl: 'https://www.applozic.com/assets/resources/images/Chat-Bot-Icon#512px.svg'
};
</script>
<script src='https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/js/widget.js'></script>
</body>
</html>
chat.html
<html>
<head>
<title>BotMan Widget</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/assets/css/chat.min.css">
</head>
<body>
<script id="botmanWidget" src='https://cdn.jsdelivr.net/npm/botman-web-widget#0/build/js/chat.js'></script>
</body>
</html>
chat.php
<?php
require_once 'vendor/autoload.php';
use BotMan\BotMan\BotMan;
use BotMan\BotMan\BotManFactory;
use BotMan\BotMan\Drivers\DriverManager;
$config = [
// Your driver-specific configuration
// "telegram" => [
// "token" => "TOKEN"
// ]
];
DriverManager::loadDriver(\BotMan\Drivers\Web\WebDriver::class);
$botman = BotManFactory::create($config);
// Give the bot something to listen for.
$botman->hears('hello', function (BotMan $bot) {
$bot->reply('Hello yourself.');
});
$botman->hears('Good Morning', function (BotMan $bot) {
$bot->reply('Hey John');
});
$botman->hears('what is the time in {city} located in {continent}' , function (BotMan $bot,$city,$continent) {
date_default_timezone_set("$continent/$city");
$reply = "The time in ".$city." ".$continent." is ".date("h:i:sa");
$bot->reply($reply);
});
$botman->fallback(function($bot) {
$bot->reply('Sorry, I did not understand these commands. Here is a list of commands I understand: ...');
});
// Start listening
$botman->listen();
?>
After checking I found may be issue with caching, I have installed APCU PHP Cache but still no luck.
I want when my socket connection in opened increase some value in my welcome.blade.php.
this is my EventClass:
// app/Events/TestEvent.php
class TestEvent implements ShouldBroadcast
{
...
public function broadcastOn()
{
return new Channel('test');
}
}
this is my route :
// routes/web.php
Route::get('/fire', function () {
event(new \App\Events\TestEvent());
return 'ok';
});
this is Echo configuration in bootstrap.js :
// resources/js/bootstrap.js
...
import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001' // this is laravel-echo-server host
});
and this is my welcome.blade.php :
// resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<script src="{{ asset('/js/app.js') }}"></script>
<script>
Echo.channel('test')
.listen('TestEvent', e => {
console.log(e)
})
</script>
</body>
</html>
but when I fire the TestEvent my welcome page console is empty.
Since you defined the broadcastOn function, you need to make sure you are actually listening to that channel name. Currently you are listening to the event class name, which is the default channel name when you don't provide the broadcastOn function.
So, change your JavaScript code to listen to .test, and make sure to include the dot in front of the name!
All is well explained here: https://laravel.com/docs/8.x/broadcasting#broadcast-name
I'm trying to send messages from my file index.php (server) to clients connected using websockets.
My javascript file to create the client connection :
var websocket_server = new WebSocket("ws://localhost:4950/");
websocket_server.onopen = function(e) {
console.log("connected");
}
websocket_server.onmessage = function(e)
{
console.log('message received from server');
}
index.php:
$msg = "Message from server";
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR,1) or die("prbl options\n");
socket_connect($sock, '127.0.0.1', 4950) or die("could not connect\n");
socket_write($sock, $msg, strlen($msg));
The client connect to the websocket is successful, but when I run the PHP file, I get nothing (no error and no message in the console).
In other words, javascript doesn't consider my socket_write as a message :/
Any ideas? :)
I have found a solution thanks to #ADyson ;)
I'm using SSE server sent events now and it works !But I'd like to know if my code is 'proper' or if there is a more 'adequate' way.
I'm using session superglobals to pass server informations changes to another file which is constantly reading it as event-stream (that's the way SSE works).
index.php :
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="jquery.js">
</script>
<script type="text/javascript" src="stream.js">
</script>
</head>
<body>
<a>Receive message</a>
</body>
</html>
stream.js (listening to the server) :
var serv = new EventSource("server.php");
serv.onmessage = function(e) {
var jdata = JSON.parse(e.data);
console.log(jdata.message);
};
serv.onopen = function(e) {
console.log('Connection opened');
}
$(document).ready(function(){
$('a').click(function(){
receive_msg();
});
});
function receive_msg(){
$.ajax({
type: "POST",
url: 'controller.php',
data: {action: 'send'}
});
}
controller.php :
<?php
session_start();
if (isset($_POST['action'])) {
$_SESSION['server']="you have received a message";
}
server.php :
<?php
session_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
if (isset($_SESSION['server'])) {
$data = array(
'message'=> $_SESSION['server']
);
$data = json_encode($data);
echo "data: {$data}\n\n";
unset($_SESSION['server']);
}
The way it works :
Clients connect to the server.php and read the file constantly. When the server wants to send a message to clients, it creates a session variable. Server.php reads the variable and pass it to my js file. Then the variable is destroyed so we pass the message only once.
I have created a chat application using the walk through on socket.io
I have added further content to the application, including database info, which meant I had to change the index.html to current session.php.
Now when I try and run the application, it just downloads a document with all the code for the page, and it does not run.
I have changed all the code to current session.php where necessary.
If I change the file name back to current session.html and change the relevant code, it then works fine....
I really need to have database info on the page, which is why it needs to be current session.php
Does anyone know why it does this? Is there a work around?
Code for index.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/currentsession', function(req, res){
res.sendFile(__dirname + '/Staff/html/current session.php');
});
app.get('/question', function(req, res){
res.sendFile(__dirname + '/Student/Question.php');
});
io.emit('some event', { for: 'everyone' });
io.on('connection', function(socket){
socket.broadcast.emit('hi');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
var nsp = io.of('/currentsession');
nsp.on('connection', function(socket){
socket.join('/currentsession');
});
var nsp = io.of('/question');
nsp.on('connection', function(socket){
socket.join('/question');
});
var nsp = io.of('/currentsession');
nsp.on('connection', function(socket){
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
var nsp = io.of('/currentsession');
nsp.on('connection', function(socket){
socket.on('go-to-page', function(data){
io.of('/question').emit('go-to-page', { href: "//selene.hud.ac.uk/u1555602"});
});
});
http.listen(4000, function(){
console.log('listening on *:4000');
});
code for current session.php
<?php include('server.php') ?>
<?php
if (!isset($_SESSION['username'])) {
$_SESSION['msg'] = "You must log in first";
header('location: sign in.php');
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Wireless Response System</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="../css/style.css" rel="stylesheet" type="text/css">
</head>
<div class="heading">
<div class="php">
<?php
if (isset($_SESSION['username'])) :
$query = ("SELECT discipline FROM user WHERE username = '".$_SESSION['username']."'");
$resultset = $conn->query($query);
while ($user = $resultset->fetch()) {
echo '<h1> Discipline:'; echo $user["discipline"]; '</h1>'; }
endif
?>
</div>
<nav>
<ul>
<form action="">
<button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io('/currentsession');
$('form').submit(function(){
socket.emit('go-to-page', $('#m').val());
$('#m').val('');
return false;
});
socket.on('go-to-page', function (data) {
window.location.replace(data.href);
});
});
</script>
res.sendFile(__dirname + '/Staff/html/current session.php');
You have written an HTTP server using Node.js.
For some HTTP requests, your server will respond by reading the source code of a PHP file and then sending it to the browser.
You need to run the PHP program and send its output, not the source code.
Typically you would do this by using a server optimised for running PHP (such as Apache HTTPD) and having the browser make the request to that server and not the one created using Node.js.
I get inconsistent duplicate inserts when running the following Laravel code: (I know I'm breaking all best practices, but this example code isolates the problem.)
App/routes/web.php:
<?php
use Illuminate\Support\Facades\DB; // NOTE: I am using the query builder, not a model
use Carbon\Carbon;
Route::get('formtest', function() {
return view('testing.index');
});
use Illuminate\Http\Request;
Route::post('formtest', function(Request $request) {
DB::table('pers2_testing_inserts')
->insert([
'data' => $request["test"],
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
});
App/resources/views/testing/index.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TESTING</title>
</head>
<body>
<form id="form" action="" method="post" novalidate autocomplete="off" onsubmit="disableAndSubmit(event)">
<input type="text" name="test" id="text_box">
<input type="submit" id="submit_button">
</form>
<script type="text/javascript">
var text_box = document.getElementById('text_box');
var submit_button = document.getElementById('submit_button');
var form = document.getElementById('form');
function disableAndSubmit(e) {
submit_button.disabled = true;
if(text_box.value !== '') {
form.submit();
} else {
e.preventDefault();
submit_button.disabled = null;
}
}
</script>
</body>
</html>
My project is built in Laravel 5.4, PHP 7.1.7. I develop on a Mac, using vagrant as a virtual machine. My production server is a Windows Server 2008 R2 Standard Computer with XAMPP v3.2.2. The inconsistent duplicate inserting ONLY happens on the production server. Here is a screenshot of a few tests on the server.
I have inserts all over in my program, and any one of them can duplicate, and it's inconsistent. It shouldn't be that way. Is there something I should change in my XAMPP configuration? PHP configuration? Is there a workaround that I can implement that would prevent this from happening on the server?
try this:
<script type="text/javascript">
var text_box = document.getElementById('text_box');
var submit_button = document.getElementById('submit_button');
var form = document.getElementById('form');
function disableAndSubmit(e) {
e.preventDefault();
submit_button.disabled = true;
if(text_box.value !== '') {
form.submit();
return true;
} else {
submit_button.disabled = false;
return false;
}
}
</script>