Skip to content

Commit c16706a

Browse files
author
ace-n
committed
Initial commit of Flex websockets sample
1 parent fa90d48 commit c16706a

File tree

13 files changed

+447
-0
lines changed

13 files changed

+447
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
.gitignore
3+
.git/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# PHP websockets sample for Google App Engine Flexible Environment
2+
3+
This sample demonstrates how to use websockets on [Google App Engine Flexible Environment](https://cloud.google.com/appengine).
4+
5+
## Running locally
6+
7+
Use the following commands to run locally:
8+
9+
```sh
10+
cd php-docs-samples/appengine/flexible/cloudsql
11+
php -S localhost:8080
12+
```
13+
14+
## Deploying
15+
Refer to the [top-level README](../README.md) for instructions on running and deploying.
16+
17+
Note that you will have to [create a firewall rule](https://cloud.google.com/sdk/gcloud/reference/compute/firewall-rules/create) that accepts traffic on port `8000`:
18+
19+
```sh
20+
gcloud compute firewall-rules create allow-8000 --allow=tcp:8000 --target-tags=websockets-allow-8000
21+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[program:socket-server]
2+
command = php %(ENV_APP_DIR)s/socket-server.php
3+
enviroment = PORT="8000"
4+
stdout_logfile = /dev/stdout
5+
stdout_logfile_maxbytes=0
6+
stderr_logfile = /dev/stderr
7+
stderr_logfile_maxbytes=0
8+
user = root
9+
autostart = true
10+
autorestart = true
11+
priority = 10
12+
stopwaitsecs = 20
13+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
runtime: php
2+
env: flex
3+
4+
# Use only a single instance, so that this local-memory-only chat app will work
5+
# consistently with multiple users. To work across multiple instances, an
6+
# extra-instance messaging system or data store would be needed.
7+
manual_scaling:
8+
instances: 1
9+
10+
11+
# For applications which can take advantage of session affinity
12+
# (where the load balancer will attempt to route multiple connections from
13+
# the same user to the same App Engine instance), uncomment the folowing:
14+
15+
# network:
16+
# session_affinity: true
17+
18+
runtime_config:
19+
document_root: .
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"require": {
3+
"cboden/ratchet": "^0.4.1",
4+
"guzzlehttp/psr7": "^1.5",
5+
"silex/silex": "^2.3",
6+
"symfony/twig-bridge": "^4.2",
7+
"twig/twig": "^1.29"
8+
},
9+
"require-dev": {
10+
"phpunit/phpunit": "^7.5",
11+
"ratchet/pawl": "^0.3.4",
12+
"react/promise": "^2.7",
13+
"clue/block-react": "^1.3",
14+
"google/cloud-tools": "^0.9.1"
15+
}
16+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{#
2+
# Copyright 2019 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#}
16+
17+
<html>
18+
<head>
19+
<title>Google App Engine Flexible Environment - PHP Websockets Chattitle>
20+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
21+
head>
22+
<body>
23+
24+
25+
<p>Chat demop>
26+
<form id="chat-form">
27+
<textarea id="chat-text" placeholder="Enter some text...">textarea>
28+
<button type="submit">Sendbutton>
29+
form>
30+
31+
<div>
32+
<p>Messages:p>
33+
<ul id="chat-response">ul>
34+
div>
35+
36+
<div>
37+
<p>Status:p>
38+
<ul id="chat-status">ul>
39+
div>
40+
41+
42+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js">script>
43+
<script>
44+
// [START gae_flex_websockets_js]
45+
$(function() {
46+
/* If the main page is served via https, the WebSocket must be served via
47+
"wss" (WebSocket Secure) */
48+
var scheme = window.location.protocol == "https:" ? 'wss://' : 'ws://';
49+
var webSocketUri = scheme
50+
+ window.location.hostname
51+
+ (location.port ? ':'+location.port: '')
52+
+ '/chat';
53+
/* Get elements from the page */
54+
var form = $('#chat-form');
55+
var textarea = $('#chat-text');
56+
var output = $('#chat-response');
57+
var status = $('#chat-status');
58+
/* Helper to keep an activity log on the page. */
59+
function log(text){
60+
status.append($('
  • ').text(text))
  • 61+
    }
    62+
    /* Establish the WebSocket connection and register event handlers. */
    63+
    var websocket = new WebSocket(webSocketUri);
    64+
    websocket.onopen = function() {
    65+
    log('Connected');
    66+
    };
    67+
    websocket.onclose = function() {
    68+
    log('Closed');
    69+
    };
    70+
    websocket.onmessage = function(e) {
    71+
    log('Message received');
    72+
    output.append($('
  • ').text(e.data));
  • 73+
    };
    74+
    websocket.onerror = function(e) {
    75+
    log('Error (see console)');
    76+
    console.log(e);
    77+
    };
    78+
    /* Handle form submission and send a message to the websocket. */
    79+
    form.submit(function(e) {
    80+
    e.preventDefault();
    81+
    var data = textarea.val();
    82+
    websocket.send(data);
    83+
    });
    84+
    });
    85+
    // [END gae_flex_websockets_js]
    86+
    script>
    87+
    body>
    88+
    html>
    Lines changed: 45 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,45 @@
    1+
    2+
    /*
    3+
    * Copyright 2019 Google LLC.
    4+
    *
    5+
    * Licensed under the Apache License, Version 2.0 (the "License");
    6+
    * you may not use this file except in compliance with the License.
    7+
    * You may obtain a copy of the License at
    8+
    *
    9+
    * http://www.apache.org/licenses/LICENSE-2.0
    10+
    *
    11+
    * Unless required by applicable law or agreed to in writing, software
    12+
    * distributed under the License is distributed on an "AS IS" BASIS,
    13+
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14+
    * See the License for the specific language governing permissions and
    15+
    * limitations under the License.
    16+
    */
    17+
    18+
    require_once __DIR__ . '/vendor/autoload.php';
    19+
    20+
    use Silex\Application;
    21+
    use Silex\Provider\TwigServiceProvider;
    22+
    use Silex\Provider\RoutingServiceProvider;
    23+
    24+
    // create the Silex application
    25+
    $app = new Application();
    26+
    $app['debug'] = true;
    27+
    28+
    // register twig
    29+
    $app->register(new TwigServiceProvider(), [
    30+
    'twig.path' => __DIR__
    31+
    ]);
    32+
    33+
    $app->register(new Silex\Provider\RoutingServiceProvider());
    34+
    35+
    $app->get('/', function () use ($app) {
    36+
    return $app['twig']->render('index.html.twig');
    37+
    });
    38+
    39+
    // @codeCoverageIgnoreStart
    40+
    if (PHP_SAPI != 'cli') {
    41+
    $app->run();
    42+
    }
    43+
    // @codeCoverageIgnoreEnd
    44+
    45+
    return $app;
    Lines changed: 13 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,13 @@
    1+
    location /chat {
    2+
    proxy_pass "http://localhost:8000";
    3+
    proxy_http_version 1.1;
    4+
    proxy_set_header Upgrade $http_upgrade;
    5+
    proxy_set_header Connection "upgrade";
    6+
    proxy_set_header Host $http_host;
    7+
    proxy_set_header X-Real-IP $remote_addr;
    8+
    }
    9+
    10+
    location / {
    11+
    # try to serve files directly, fallback to the front controller
    12+
    try_files $uri /$front_controller_file$is_args$args;
    13+
    }
    Lines changed: 31 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,31 @@
    1+
    xml version="1.0" encoding="UTF-8"?>
    2+
    17+
    <phpunit bootstrap="test/bootstrap.php" colors="true">
    18+
    <testsuites>
    19+
    <testsuite name="default">
    20+
    <directory>testdirectory>
    21+
    testsuite>
    22+
    testsuites>
    23+
    <logging>
    24+
    <log type="coverage-clover" target="build/logs/clover.xml"/>
    25+
    logging>
    26+
    <filter>
    27+
    <whitelist>
    28+
    <file>socket_demo.phpfile>
    29+
    whitelist>
    30+
    filter>
    31+
    phpunit>
    Lines changed: 68 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,68 @@
    1+
    2+
    /**
    3+
    * Copyright 2019 Google LLC.
    4+
    *
    5+
    * Licensed under the Apache License, Version 2.0 (the "License");
    6+
    * you may not use this file except in compliance with the License.
    7+
    * You may obtain a copy of the License at
    8+
    *
    9+
    * http://www.apache.org/licenses/LICENSE-2.0
    10+
    *
    11+
    * Unless required by applicable law or agreed to in writing, software
    12+
    * distributed under the License is distributed on an "AS IS" BASIS,
    13+
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14+
    * See the License for the specific language governing permissions and
    15+
    * limitations under the License.
    16+
    */
    17+
    18+
    # [START gae_flex_websockets_app]
    19+
    use Ratchet\MessageComponentInterface;
    20+
    use Ratchet\ConnectionInterface;
    21+
    22+
    // Install composer dependencies with "composer install"
    23+
    // @see http://getcomposer.org for more information.
    24+
    require __DIR__ . '/vendor/autoload.php';
    25+
    26+
    // Forwards any incoming messages to all connected clients
    27+
    class SocketDemo implements MessageComponentInterface
    28+
    {
    29+
    protected $clients;
    30+
    31+
    public function __construct()
    32+
    {
    33+
    $this->clients = new \SplObjectStorage;
    34+
    }
    35+
    36+
    public function onOpen(ConnectionInterface $conn)
    37+
    {
    38+
    $this->clients->attach($conn);
    39+
    echo "Connection opened!\n";
    40+
    echo "\t" . $this->clients->count() . " connection(s) active.\n";
    41+
    }
    42+
    43+
    public function onMessage(ConnectionInterface $from, $msg)
    44+
    {
    45+
    $output = "Message received: " . $msg . "\n";
    46+
    echo $output;
    47+
    foreach ($this->clients as $client) {
    48+
    $client->send($output);
    49+
    }
    50+
    }
    51+
    52+
    public function onClose(ConnectionInterface $conn)
    53+
    {
    54+
    $this->clients->detach($conn);
    55+
    echo "Connection closed gracefully!\n";
    56+
    echo "\t" . $this->clients->count() . " connection(s) active.\n";
    57+
    }
    58+
    59+
    public function onError(ConnectionInterface $conn, \Exception $e)
    60+
    {
    61+
    $conn->close();
    62+
    echo "Connection closed due to error: " . $e->getMessage() . "\n";
    63+
    echo "\t" . $this->clients->count() . " connection(s) active.\n";
    64+
    }
    65+
    }
    66+
    # [END gae_flex_websockets_app]
    67+
    68+
    return new SocketDemo;
    Lines changed: 44 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,44 @@
    1+
    2+
    /**
    3+
    * Copyright 2019 Google LLC.
    4+
    *
    5+
    * Licensed under the Apache License, Version 2.0 (the "License");
    6+
    * you may not use this file except in compliance with the License.
    7+
    * You may obtain a copy of the License at
    8+
    *
    9+
    * http://www.apache.org/licenses/LICENSE-2.0
    10+
    *
    11+
    * Unless required by applicable law or agreed to in writing, software
    12+
    * distributed under the License is distributed on an "AS IS" BASIS,
    13+
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14+
    * See the License for the specific language governing permissions and
    15+
    * limitations under the License.
    16+
    */
    17+
    18+
    // Install composer dependencies with "composer install"
    19+
    // @see http://getcomposer.org for more information.
    20+
    require __DIR__ . '/vendor/autoload.php';
    21+
    require_once __DIR__ . '/socket-demo.php';
    22+
    23+
    use Ratchet\Server\IoServer;
    24+
    use Ratchet\Http\HttpServer;
    25+
    use Ratchet\WebSocket\WsServer;
    26+
    27+
    $socketDemo = new SocketDemo;
    28+
    29+
    $port = 8000;
    30+
    31+
    $server = IoServer::factory(
    32+
    new HttpServer(
    33+
    new WsServer(
    34+
    $socketDemo
    35+
    )
    36+
    ),
    37+
    $port
    38+
    );
    39+
    40+
    if (PHP_SAPI == 'cli') {
    41+
    $server->run();
    42+
    }
    43+
    44+
    return $server;
    Lines changed: 22 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,22 @@
    1+
    2+
    /**
    3+
    * Copyright 2016 Google Inc.
    4+
    *
    5+
    * Licensed under the Apache License, Version 2.0 (the "License");
    6+
    * you may not use this file except in compliance with the License.
    7+
    * You may obtain a copy of the License at
    8+
    *
    9+
    * http://www.apache.org/licenses/LICENSE-2.0
    10+
    *
    11+
    * Unless required by applicable law or agreed to in writing, software
    12+
    * distributed under the License is distributed on an "AS IS" BASIS,
    13+
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14+
    * See the License for the specific language governing permissions and
    15+
    * limitations under the License.
    16+
    */
    17+
    require __DIR__ . '/../vendor/autoload.php';
    18+
    require_once __DIR__ . '/../../../../testing/FileUtil.php';
    19+
    20+
    use Google\Cloud\TestUtils\PHPUnit4To6Shim;
    21+
    22+
    PHPUnit4To6Shim::install();

    0 commit comments

    Comments
     (0)