From fbfbe5a13beea537f361c71483eef2dfbf502400 Mon Sep 17 00:00:00 2001 From: Lang Date: Tue, 18 Oct 2016 15:58:53 +0200 Subject: [PATCH] working websocket client and server w/o session handling and storage --- app/config/config.yml | 7 +- package.json | 2 +- .../SeekerBundle/Resources/config/config.yml | 24 +++++ .../Resources/config/pubsub/routing.yml | 14 +++ .../Resources/config/services.yml | 23 +++++ .../Resources/public/js/mine-seeker/app.js | 49 ++++++++-- .../Resources/views/Game/play.html.twig | 1 + src/Mine/SeekerBundle/Rpc/AcmeRpc.php | 35 ++++++++ src/Mine/SeekerBundle/Topic/AcmeTopic.php | 89 +++++++++++++++++++ 9 files changed, 229 insertions(+), 15 deletions(-) create mode 100644 src/Mine/SeekerBundle/Resources/config/config.yml create mode 100644 src/Mine/SeekerBundle/Resources/config/pubsub/routing.yml create mode 100644 src/Mine/SeekerBundle/Rpc/AcmeRpc.php create mode 100644 src/Mine/SeekerBundle/Topic/AcmeTopic.php diff --git a/app/config/config.yml b/app/config/config.yml index 48d8fcc..6bdfc76 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -3,6 +3,7 @@ imports: - { resource: services.yml } - { resource: "@JotunheimrAdminBundle/Resources/config/config.yml" } - { resource: "@JotunheimrUserBundle/Resources/config/config.yml" } + - { resource: "@MineSeekerBundle/Resources/config/config.yml" } - { resource: "@MineSeekerBundle/Resources/config/services.yml" } # Put parameters here that don't need to change on each machine where the app is deployed @@ -74,9 +75,3 @@ fos_user: db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel' firewall_name: main user_class: Jotunheimr\UserBundle\Entity\User - -# Web Socket Configuration -gos_web_socket: - server: - port: 8080 #The port the socket server will listen on - host: 127.0.0.1 #The host ip to bind to diff --git a/package.json b/package.json index 84c2278..25d3cb4 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "babel-preset-react": "^6.11.1", "react": "^15.3.2", "react-dom": "^15.3.2", - "react-websocket": "^1.1.6" + "react-sound": "^0.5.2" }, "devDependencies": {}, "scripts": { diff --git a/src/Mine/SeekerBundle/Resources/config/config.yml b/src/Mine/SeekerBundle/Resources/config/config.yml new file mode 100644 index 0000000..56a5a99 --- /dev/null +++ b/src/Mine/SeekerBundle/Resources/config/config.yml @@ -0,0 +1,24 @@ +# Web Socket Configuration +gos_web_socket: + # for user ex.: var _WS_URI = "ws://{{ gos_web_socket_server_host }}:{{ gos_web_socket_server_port }}"; + shared_config: false + server: + port: 8080 # The port the socket server will listen on + host: 127.0.0.1 # The host IP to bind to + router: + resources: + - "@MineSeekerBundle/Resources/config/pubsub/routing.yml" + client: + firewall: secured_area # Can be an array of firewalls + session_handler: "@session.handler.pdo" +# storage: +# driver: "@gos_web_socket.client_storage.driver.predis" +# driver: "@gos_web_socket.server.in_memory.client_storage.driver" +# ttl: 28800 # (optionally) time to live if you use redis driver +# prefix: client # (optionally) prefix if you use redis driver, create key "client:1" instead key "1" + +# PDO Session Handler Configuration +framework: + session: + handler_id: session.handler.pdo +# diff --git a/src/Mine/SeekerBundle/Resources/config/pubsub/routing.yml b/src/Mine/SeekerBundle/Resources/config/pubsub/routing.yml new file mode 100644 index 0000000..a86d022 --- /dev/null +++ b/src/Mine/SeekerBundle/Resources/config/pubsub/routing.yml @@ -0,0 +1,14 @@ +# Topic Configuration +acme_topic: + channel: acme/channel + handler: + callback: 'acme.topic' #related to the getName() of your topic + +# Remote Procedure Call Configuration +acme_rpc: + channel: sample/{method} + handler: + callback: 'acme.rpc' #related to the getName() or your RPC service + requirements: + method: + path: "[a-z_]+" diff --git a/src/Mine/SeekerBundle/Resources/config/services.yml b/src/Mine/SeekerBundle/Resources/config/services.yml index 27a3135..31b4824 100644 --- a/src/Mine/SeekerBundle/Resources/config/services.yml +++ b/src/Mine/SeekerBundle/Resources/config/services.yml @@ -2,3 +2,26 @@ services: # mine_seeker.example: # class: Mine\SeekerBundle\Example # arguments: ["@service_id", "plain_value", %parameter%] + + session.handler.pdo: + class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler + arguments: + - "mysql:dbname=%database_name%" + - { db_table: sessions, db_username: myuser, db_password: mypassword } + +# gos_web_scocket.client_storage.driver.predis: +# class: Gos\Bundle\WebSocketBundle\Client\Driver\PredisDriver +# arguments: +# - "@cache.adapter.redis" + + acme_hello.topic_sample_service: + class: Mine\SeekerBundle\Topic\AcmeTopic + tags: + - { name: gos_web_socket.topic } +# arguments: +# - { clientManipulator: "@gos_web_socket.websocket.client_manipulator" } + + acme_hello.rpc_sample_service: + class: Mine\SeekerBundle\Rpc\AcmeRpc + tags: + - { name: gos_web_socket.rpc } diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js index ff61d2d..446f9dd 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js @@ -2,14 +2,47 @@ import React from 'react'; import GridControl from './grid/grid-control'; class MineSeeker extends React.Component { - // /** after rendering */ - // componentDidMount() { - // this.connection = new WebSocket('ws://127.0.0.1:8080'); - // - // this.connection.onmessage = evt => { - // // console.log(evt.data); - // }; - // } + /** after rendering */ + componentDidMount() { + var websocket = WS.connect("ws://127.0.0.1:8080"); + + /** session is an Autobahn JS WAMP session. */ + websocket.on("socket/connect", function (session) { + console.info("Successfully Connected!"); + + session.subscribe("acme/channel", function(uri, payload){ + console.log("Received message", payload.msg); + }); + + // session.call("sample/sum", {"term1": 2, "term2": 5}).then( + // function (result) { + // console.log("RPC Valid!", result); + // }, + // function (error, desc) { + // console.log("RPC Error", error, desc); + // } + // ); + + session.publish("acme/channel", {msg: "This is a message!"}); + + // session.publish("acme/channel", {msg: "I'm leaving, I will not see the next message"}); + // + // session.unsubscribe("acme/channel"); + // + // session.publish("acme/channel", {msg: "I won't see this"}); + // + // session.subscribe("acme/channel", function (uri, payload) { + // console.log("Received message", payload.msg); + // }); + // + // session.publish("acme/channel", {msg: "I'm back!"}); + }); + + /** error provides us with some insight into the disconnection: error.reason and error.code */ + websocket.on("socket/disconnect", function (error) { + console.info("Disconnected for " + error.reason + " with code " + error.code); + }); + } render() { return ( diff --git a/src/Mine/SeekerBundle/Resources/views/Game/play.html.twig b/src/Mine/SeekerBundle/Resources/views/Game/play.html.twig index 78f5b48..35e0a51 100644 --- a/src/Mine/SeekerBundle/Resources/views/Game/play.html.twig +++ b/src/Mine/SeekerBundle/Resources/views/Game/play.html.twig @@ -13,6 +13,7 @@ {% block javascripts %} {{ parent() }} + {{ ws_client() }} {% endblock %} diff --git a/src/Mine/SeekerBundle/Rpc/AcmeRpc.php b/src/Mine/SeekerBundle/Rpc/AcmeRpc.php new file mode 100644 index 0000000..ea65cd5 --- /dev/null +++ b/src/Mine/SeekerBundle/Rpc/AcmeRpc.php @@ -0,0 +1,35 @@ + array_sum($params)); + } + + /** + * Name of RPC, use for pubsub router (see step3) + * + * @return string + */ + public function getName() + { + return 'acme.rpc'; + } +} diff --git a/src/Mine/SeekerBundle/Topic/AcmeTopic.php b/src/Mine/SeekerBundle/Topic/AcmeTopic.php new file mode 100644 index 0000000..dc617e7 --- /dev/null +++ b/src/Mine/SeekerBundle/Topic/AcmeTopic.php @@ -0,0 +1,89 @@ +clientManipulator = $clientManipulator; +// } + + /** + * This will receive any Subscription requests for this topic. + * + * @param ConnectionInterface $connection + * @param Topic $topic + * @param WampRequest $request + * @return void + */ + public function onSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request) + { +// $user = $this->clientManipulator->getClient($connection); + $user = ""; + //this will broadcast the message to ALL subscribers of this topic. + $topic->broadcast([ + 'msg' => $connection->resourceId . " has joined " . $topic->getId(), + 'user' => $user + ]); + } + + /** + * This will receive any UnSubscription requests for this topic. + * + * @param ConnectionInterface $connection + * @param Topic $topic + * @param WampRequest $request + * @return void + */ + public function onUnSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request) + { + //this will broadcast the message to ALL subscribers of this topic. + $topic->broadcast(['msg' => $connection->resourceId . " has left " . $topic->getId()]); + } + + /** + * This will receive any Publish requests for this topic. + * + * @param ConnectionInterface $connection + * @param Topic $topic + * @param WampRequest $request + * @param $event + * @param array $exclude + * @param array $eligible + * @return mixed|void + * @internal param Topic $Topic + * @internal param array $eligibles + */ + public function onPublish(ConnectionInterface $connection, Topic $topic, WampRequest $request, $event, array $exclude, array $eligible) + { + /* + $topic->getId() will contain the FULL requested uri, so you can proceed based on that + if ($topic->getId() == "acme/channel/shout") + //shout something to all subs. + */ + $topic->broadcast([ + 'msg' => $event + ]); + } + + /** + * Like RPC is will use to prefix the channel + * @return string + */ + public function getName() + { + return 'acme.topic'; + } +} \ No newline at end of file