friends-of-reactphp / zmq Goto Github PK
View Code? Open in Web Editor NEWZeroMQ bindings for ReactPHP.
License: MIT License
ZeroMQ bindings for ReactPHP.
License: MIT License
I get this error when I try and run a test of React. It error is being generated in the SocketWrapper.php class in the ZMQ directory. I am trying to create a server so I am running the command from the command line.
I am currently running:
PHP Version: 5.3.24
ZMQ Version: 3.2.0
OS: Windows 7 Home
Any help would be appreciated?
How can I have multiple push workers within multiple pull workers, is that possible?
A only can have multi pull and single push, as in README's example:
$push->connect()
$pull->bind()
Or single pull and multi pushes:
$push->bind()
$pull->connect()
When I try to set both as connect
the pulls doesn't receive the messages.
Otherwise, trying to start more than one process with bind
it throws:
ZMQSocketException: Failed to bind the ZMQ: Address in use
Should I have a middleware? 🤔
5555 5556
push --| 5555 --> 5556 | pull
push --|-- pull & push -- | pull
push --| bind / bind | pull
connect connect
The @mixin should be at the end of the class comment. Currently some IDEs interpret the @mixin as part of the description, and don't properly recognize ZMQContext functions like getSocket().
Also, @method is unnecessary because of it, but @method should also be written with the parameters, so @method SocketWrapper getSocket(($type, $persistent_id = null, $on_new_socket = null))
instead of @method SocketWrapper getSocket
.
Hi,
we’re going to package this for Debian as part of the effort to package Movim, and it would tremendously help us if you could please tag a formal release within the next… 72 hours or so, if possible early (we’re currently having a hacking session).
Thanks in advance!
I am using composer.phar version
424407af720a7a3022091d928c65e3fc7873455b
Below is the error message:
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for react/zmq 0.1.x-dev -> satisfiable by react/zmq[0.1.x-dev].
- react/zmq 0.1.x-dev requires ext-zmq * -> the requested PHP extension zmq is missing from your system.
Hi,
The only question is to know about if you plan release a new version. I am interesting to get EventLoop 0.5 support and all updates from the last release.
Thanks a lot for your work and effort
I'm trying to add Ratchet and ZMQ to my Symfony2 project. I have added the following two lines to my composer.json file:
"cboden/Ratchet": "0.2.*",
"react/zmq": "0.1.*"
When I run composer.phar to download these new packages I get the following error:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- react/zmq v0.1.1 requires ext-zmq * -> the requested PHP extension zmq is missing from your system.
- react/zmq v0.1.0 requires ext-zmq * -> the requested PHP extension zmq is missing from your system.
- Installation request for react/zmq 0.1.* -> satisfiable by react/zmq v0.1.0, react/zmq v0.1.1.
Any ideas what I'm missing? Do I need to also add that extension manually?
Regards
Problem 1
- Can only install one of: evenement/evenement[v2.0.0, v1.0.0].
- Can only install one of: evenement/evenement[v2.0.0, v1.0.0].
- react/zmq v0.3.0 requires evenement/evenement ~2.0 -> satisfiable by evenement/evenement[v2.0.0].
- Installation request for react/zmq 0.3.* -> satisfiable by react/zmq[v0.3.0].
- Installation request for evenement/evenement == 1.0.0.0 -> satisfiable by evenement/evenement[v1.0.0].
Regards
Attempting to install nets me a version conflict with Evenement. It looks as if it bumped major versions over the summer after several years of being at 2.
vagrant@client /vagrant (develop*) $ composer require react/zmq
Using version ^0.3.0 for react/zmq
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for react/zmq ^0.3.0 -> satisfiable by react/zmq[v0.3.0].
- Conclusion: remove evenement/evenement v3.0.1
- Conclusion: don't install evenement/evenement v3.0.1
- react/zmq v0.3.0 requires evenement/evenement ~2.0 -> satisfiable by evenement/evenement[v2.0.0, v2.1.0].
- Can only install one of: evenement/evenement[v2.0.0, v3.0.1].
- Can only install one of: evenement/evenement[v2.1.0, v3.0.1].
- Installation request for evenement/evenement (locked at v3.0.1) -> satisfiable by evenement/evenement[v3.0.1].
Installation failed, reverting ./composer.json to its original content.
im trying to push a notification to some clients, so i use ZMQ (Push integration) module. everything is ok and all users can connect and subscribe, but onBlogEntry
does not run. it seems tcp://127.0.0.1:5555
does not work fine. i use wampserver , PHP5.5 and Apache 2.4 on windows 10. Thanks in advance for your help.
here are my server codes( receiver ):
<?php
require 'vendor/autoload.php';
require 'classes/WebSocketCon.php';
$loop = React\EventLoop\Factory::create();
$pusher = new WebSocketCon;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8081, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
here are sender codes :
require_once("vendor/autoload.php");
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH,"pusher");
$socket->connect("tcp://127.0.0.1:5555");
$entryData = array(
'category' => "sm"
, 'title' => "saleh"
, 'when' => time()
);
$socket->send(json_encode($entryData));
here are javascripts :
var conn = new ab.Session('ws://localhost:8081',
function() {
conn.subscribe('sm', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log(data);
alert('New article published to category "' + topic + '" : ' + data.title);
});
},
function() {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
It would be extremely useful having public method countMessages() in SocketWrapper that returns count of $this->buffer->messages array when called. This could be used in case of using SocketWrapper in messenger class that limits buffer of outgoing and incoming messages to save RAM. Keep in mind that not having this option and leaving buffering to setting ZMQ::SOCKOPT_HWM / ZMQ::SOCKOPT_SNDHWM / ZMQ::SOCKOPT_RCVHWM does not prevent PHP code from declaring too much memory in Buffer.php.
I'm having a hard time with a project of mine where I use React + Ratchet as a WAMP server. React is also set up with ZMQ and recieves data from a pipeline. What I experience is that this pipeline stops working and I have to restart my React + Ratchet server after varying periods of time.
In order to track down what was going on I went back to basics and created a vanilla ZMQ pipeline where I in one process pull and write a minus (-) while in another process push and write a plus (+).
See the pull code here: https://gist.github.com/3924664
See the push code here: https://gist.github.com/3924672
When running this it works as I expect, I get a (seemingly) neverending mix of pluses and minuses.
See a test run here: https://gist.github.com/3924682
(remember to scroll horizontally ;) )
OK, so the basics work. What I did next was to implement the same minimalistic pull code with React+ZMQ.
See the React pull implementation here: https://gist.github.com/3924668
When running this it starts out fine, but after a little bit I end up only pushing to the pipeline, the pulls seem to hang for some reason. My question to you - whats up with that?
See a test run with React pull here: https://gist.github.com/3924709
(remember to scroll horizontally ;) )
Setup:
PHP 5.3.10-1ubuntu3.2 with Suhosin-Patch (cli) (built: Jun 13 2012 17:20:55)
libzmq version => 2.2.0
react/event-loop v0.2.1
react/socket v0.2.1
react/zmq dev-master
no document,why?
Hello,
I'm trying to use REQ/REP with reactphp-zmq. While it works properly with the PHP extension, it seems to have some issues.
$loop = React\EventLoop\Factory::create();
$context = new React\ZMQ\Context($loop);
$requester = $context->getSocket(ZMQ::SOCKET_REQ);
$requester->connect('tcp://127.0.0.1:5555');
$i = 0;
$loop->addPeriodicTimer(1, function () use (&$i, $requester) {
$i++;
echo "(out) -> $i\n";
$requester->send($i);
$reply = $requester->recv();
echo "(in) <- $reply\n";
});
$loop->run();
Here is the output:
$ php test.php
-> 1
PHP Fatal error: Uncaught ZMQSocketException: Failed to receive message: Operation cannot be accomplished in current state in /var/www/apps/cadi-back/vendor/react/zmq/src/SocketWrapper.php:171
Stack trace:
#0 [internal function]: ZMQSocket->recv()
#1 /var/www/apps/cadi-back/vendor/react/zmq/src/SocketWrapper.php(171): call_user_func_array(Array, Array)
#2 /var/www/apps/cadi-back/test.php(19): React\ZMQ\SocketWrapper->__call('recv', Array)
#3 /var/www/apps/cadi-back/vendor/react/event-loop/src/Timer/Timers.php(96): {closure}(Object(React\EventLoop\Timer\Timer))
#4 /var/www/apps/cadi-back/vendor/react/event-loop/src/StreamSelectLoop.php(183): React\EventLoop\Timer\Timers->tick()
#5 /var/www/apps/cadi-back/test.php(23): React\EventLoop\StreamSelectLoop->run()
#6 {main}
thrown in /var/www/apps/cadi-back/vendor/react/zmq/src/SocketWrapper.php on line 171
I understand that this code is not optimal considering I send each second no matter if the reply occured (while it must be according to zmq protocol). But here the issue is about ->recv()
not working in "current state" (which should be the good one).
[edit] this is probably due to the buffer that delays the send
to "later" while the recv
is not delayed. Not a trivial problem.
Forked children cause assertion failure
zeromq/php-zmq#59
In React\ZMQ\Context
ZMQContext::__construct ([ integer $io_threads = 1 [, boolean $is_persistent = true ]] )
function __construct(LoopInterface $loop, \ZMQContext $context = null, $io_threads = 1, $is_persistent = true){
$this->context = $context ?: new \ZMQContext($io_threads, $is_persistent );
}
React now requires 2.0
in 0.4.0 so you can't install this as the dependencies conflict.
This library seems to be using ReactPHP's event loop with ZMQ. However, it's using an old version of ReactPHP. I was hoping I could use some of ReactPHP's newer Async/Promise tasks but that would require updating ReactPHP. Would this library allow updating ReactPHP to the latest version?
Loading composer repositories with package information
Updating dependencies (including require-dev)
$ php test-push.php
PHP Fatal error: Class 'React\EventLoop\Factory' not found in ... test-push.php on line 3
Any idea of how to fix this?
Correct me if i am wrong, but zeromq has it's own zmq_poll which could be used to create a React Event Loop. I'm wondering why there is no such implementation in this bindings lib. Is it a technical issue, or just on the todo list?
From what i know poll is more performant than select and zeromq has issues using other event loops such as libev, libuv or libevent.
It seems there is a critical bug when trying to call end() method on SocketWrapper instance before handleEvent() completed sending all messages. If that happens to be the case, then PHP throws fatal error:
PHP Fatal error: Call to a member function getSockOpt() on a non-object in [...]\vendor\react\zmq\src\React\ZMQ\
SocketWrapper.php on line 35
It can be duplicated when scheduling big amount of messages - for example:
for ($i=0; $i<1000000; ++$i)
{
$socketWrapper->send($something);
}
$socketWrapper->end();
It can become especially bothersome, when writing distributed application and both send and end methods are callback for different events.
"require": {
"react/zmq": "0.2.*"
}
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for react/zmq 0.2.* -> satisfiable by react/zmq[v0.2.0].
- react/zmq v0.2.0 requires ext-zmq * -> the requested PHP extension zmq is missing from your system.
I tried everything, but nothing works. I looked at all the information on the Internet. I have Windows 10 PC. I am using ZeroMQ with Ratchet php server.
Specifically this is the problem:
Problem 1 - Installation request for react/zmq 0.4.0 -> satisfiable by react/zmq[v0.4.0]. - react/zmq v0.4.0 requires ext-zmq * -> the requested PHP extension zmq is missing from your system.
The is how my composer.json
file looks like:
{ "autoload": { "psr-4": { "MyApp\\": "src" } }, "require": { "cboden/ratchet": "^0.4.2", "react/zmq": "0.4.0" } }
Attached is the screenshot of the error that I am getting on Git bash.
Currently there is a single message
event. If there is only one message, the emitted value is that value. If on the other hand, it is a multi-part message, then the emitted value is an array of messages.
This is implicit and possibly confusing. It should be changed so that:
message
is only emitted for single-part messages.messages
is emitted for all messages and always emits an array.Alternative naming might be multi-message
, multipart-message
or just multipart
.
The ext-zmq
extension is known to have compatibility issues with PHP 7.3 at the moment. I'm opening this issue only as a heads-up, the actual issue is already reported upstream (zeromq/php-zmq#193) and there's little we can do about this in this library.
Hello, I was wondering if this is the correct way to go about sending individual messages.
It was reported in a Ratchet issue this library can't be installed with Evenement 3.
I just updated my project with the latest version and now I get the following warnings when warming up the cache (Symfony 2.5.0 project).
Warning: Ambiguous class resolution, "React\Stream\ThroughStream" was found in both "/www/vendor/react/stream/ThroughStream.php" and "/www/vendor/react/stream/React/Stream/ThroughStream.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\CompositeStream" was found in both "/www/vendor/react/stream/CompositeStream.php" and "/www/vendor/react/stream/React/Stream/CompositeStream.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\Buffer" was found in both "/www/vendor/react/stream/Buffer.php" and "/www/vendor/react/stream/React/Stream/Buffer.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\BufferedSink" was found in both "/www/vendor/react/stream/BufferedSink.php" and "/www/vendor/react/stream/React/Stream/BufferedSink.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\ReadableStream" was found in both "/www/vendor/react/stream/React/Stream/ReadableStream.php" and "/www/vendor/react/stream/ReadableStream.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\ReadableStreamInterface" was found in both "/www/vendor/react/stream/React/Stream/ReadableStreamInterface.php" and "/www/vendor/react/stream/ReadableStreamInterface.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\WritableStream" was found in both "/www/vendor/react/stream/React/Stream/WritableStream.php" and "/www/vendor/react/stream/WritableStream.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\Util" was found in both "/www/vendor/react/stream/React/Stream/Util.php" and "/www/vendor/react/stream/Util.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\Stream" was found in both "/www/vendor/react/stream/React/Stream/Stream.php" and "/www/vendor/react/stream/Stream.php", the first will be used.
Warning: Ambiguous class resolution, "React\Stream\WritableStreamInterface" was found in both "/www/vendor/react/stream/React/Stream/WritableStreamInterface.php" and "/www/vendor/react/stream/WritableStreamInterface.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\LibEvLoop" was found in both "/www/vendor/react/event-loop/LibEvLoop.php" and "/www/vendor/react/event-loop/React/EventLoop/LibEvLoop.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\Factory" was found in both "/www/vendor/react/event-loop/React/EventLoop/Factory.php" and "/www/vendor/react/event-loop/Factory.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\LoopInterface" was found in both "/www/vendor/react/event-loop/React/EventLoop/LoopInterface.php" and "/www/vendor/react/event-loop/LoopInterface.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\StreamSelectLoop" was found in both "/www/vendor/react/event-loop/React/EventLoop/StreamSelectLoop.php" and "/www/vendor/react/event-loop/StreamSelectLoop.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\Timer\TimerInterface" was found in both "/www/vendor/react/event-loop/React/EventLoop/Timer/TimerInterface.php" and "/www/vendor/react/event-loop/Timer/TimerInterface.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\Timer\Timer" was found in both "/www/vendor/react/event-loop/React/EventLoop/Timer/Timer.php" and "/www/vendor/react/event-loop/Timer/Timer.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\Timer\Timers" was found in both "/www/vendor/react/event-loop/React/EventLoop/Timer/Timers.php" and "/www/vendor/react/event-loop/Timer/Timers.php", the first will be used.
Warning: Ambiguous class resolution, "React\EventLoop\LibEventLoop" was found in both "/www/vendor/react/event-loop/React/EventLoop/LibEventLoop.php" and "/www/vendor/react/event-loop/LibEventLoop.php", the first will be used.
Everything seems to be working fine so far though...
TCP connection does not work on my local PC and it does not display any error.
here is my pull.php :
<?php
require 'vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5050');
$pull->on('error', function ($e) {
var_dump($e->getMessage());
});
$pull->on('message', function ($msg) {
echo "Received: $msg\n";
});
$loop->run();
and here is my push.php :
<?php
require 'vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$context = new React\ZMQ\Context($loop);
$push = $context->getSocket(ZMQ::SOCKET_PUSH);
$push->connect('tcp://127.0.0.1:5050');
$push->on('error', function ($e) {
var_dump($e->getMessage());
});
$i = 0;
$loop->addPeriodicTimer(1, function () use (&$i, $push) {
$i++;
echo "sending $i\n";
$push->send($i);
});
$loop->run();
also i disabled my firewall , but it still does not work. im using wampserver. here is my comoser.js:
{
"require": {
"cboden/ratchet": "^0.4.0",
"react/zmq": "^0.3.0"
}
}
I'm using Fedora 26 with turned off selinux
When I try to create new instance of
new \React\Socket\Server( "127.0.0.1:5555", $loop);
[RuntimeException]
Failed to listen on "tcp://127.0.0.1:5555": Address already in use
$ sudo lsof -i tcp:5555
$
Hi,
I have setup a little demo with a publisher sending to different "channels" and workers subscribing to particular channels.
My worker starts a React loop with the SUB socket pluged in and the callback defined with the on('message', array($this, 'method'))
syntax
According to the doc, for sending to a particular channel you have to send a multi-part message
http://zguide.zeromq.org/php:all#Pub-Sub-Message-Envelopes
But in react, only the first part of a multipart message is returned to callback
https://github.com/reactphp/zmq/blob/master/src/SocketWrapper.php#L57
And then in the callback i only get the subscription channel and not the message itself
I think the actual strategy is valid for REQ/REP sockets which adds the 0 frame. For PUB/SUB the callback should get only the message or both the message and the subscription
Anyway, React is great and the ZMQ bindings offers some really nice possibilities, really easy to implement! Thank you for that
你好,我使用官网的例子,成功推送消息到客户端,但是发现会重复推送,我的代码如下:
Hello, I use the official website of the example, the success of the news push to the client, but found that the push will be repeated, my code is as follows:
require dirname(DIR) . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$alimama = new WebSocket\Alimama;
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:55556'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($alimama, 'onRequest'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
$alimama
)
),
$webSock
);
$loop->run();
===============================
public function detail(){
echo "商品ID为:".I('get.id');
echo "
目标:在client.html页面应该收到此ID";
$data['id'] = I('get.id');
//websocket推送
$lock = "./bin/ws.lock";
if(file_exists($lock)){
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH);
$socket->connect("tcp://localhost:55556");
$socket->send(json_encode($data));
}
}
=============================
Hello,
Have you a use case or an example with epgm ?
Thanks.
Hi,
I want to do an asynchronous router to dealer messaging with React but it isn't working. The code in http://zguide.zeromq.org/php:rtdealer is working, but I can't identify what I'm doing different.
Here is my code:
$context = new React\ZMQ\Context($loop);
$worker = $context->getSocket(\ZMQ::SOCKET_DEALER);
$worker->setSockOpt(\ZMQ::SOCKOPT_IDENTITY, 'A');
$worker->connect('tcp://127.0.0.1:5556');
$worker->send('END');
$worker->on('error', function ($e) {
var_dump($e->getMessage());
});
$worker->on('messages', function($msg) use ($worker) {
echo 'Dealer messages'. PHP_EOL;
var_dump($msg);
});
$worker->on('message', function($msg) use ($worker) {
echo 'Dealer message'. PHP_EOL;
var_dump($msg);
});
$router = $context->getSocket(\ZMQ::SOCKET_ROUTER);
$router->bind('tcp://127.0.0.1:5556');
$i = 0;
$loop->addPeriodicTimer(1, function (React\EventLoop\Timer\Timer $timer) use (&$i, $router) {
echo 'Time to send!'. PHP_EOL;
$i++;
$router->send('A', \ZMQ::MODE_SNDMORE);
$router->send('END');
});
$router->on('messages', function($msg) use ($router) {
echo 'Router messages'. PHP_EOL;
var_dump($msg);
});
$router->on('message', function($msg) {
echo 'Router message'. PHP_EOL;
var_dump($msg);
});
$loop->run();
The problem is that only the dealer sends the first message "END". After that, router tries to send messages but dealer does not receive them.
Also, this function seems to be only called once:
// \React\ZMQ\SocketWrapper
public function handleReadEvent()
{
$messages = $this->socket->recvmulti(ZMQ::MODE_NOBLOCK);
echo 'Receiving...'; // Added
var_dump($messages); // Added
if ($messages !== false) {
if (count($messages) === 1) {
$this->emit('message', array($messages[0]));
}
$this->emit('messages', array($messages));
}
}
The output is:
Receiving...array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Router messages
array(2) {
[0]=>
string(1) "A"
[1]=>
string(3) "END"
}
Time to send!
Time to send!
Time to send!
Time to send!
Time to send!
...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.