esl-client / esl-client Goto Github PK
View Code? Open in Web Editor NEWA Fork from http://git.freeswitch.org/git/freeswitch-contrib/tree/dvarnes/java/esl-client
License: Apache License 2.0
A Fork from http://git.freeswitch.org/git/freeswitch-contrib/tree/dvarnes/java/esl-client
License: Apache License 2.0
inbound的模式,是否可以集群部署?部署多个实例,每个实例都会收到监听到的事件吗?
自定义的EslFrameDecoder类中,未释放堆外内存,导致堆内存只增不减,到了一定程度就异常了
Where are class 'EventFormat' , 'IClientHandlerFactory' and 'IClientHandler'
What's the use of 'InetSocketAddress' ?
When I send bgapi command on the one client, The client is stucked! Is it not real background api?
In file https://github.com/esl-client/esl-client/blob/master/src/main/java/org/freeswitch/esl/client/internal/AbstractEslClientHandler.java at line 148.
"backgroundJobs" was not added when "BACKGROUND_JOB" was received
The same code, "inbound" gets the return value, but "outbound" doesn't.
"outbound" onConnect code :
CompletableFuture<EslEvent> future = context.sendBackgroundApiCommand("version","");
EslEvent e = future.get(); // It's blocked because( backgroundJobs.remove(backgroundUuid); is null)
logger.info("===eslevent {}",e);
private String readLine(ByteBuf buffer, int maxLineLength) throws TooLongFrameException {
StringBuilder sb = new StringBuilder(64);
// while (buffer.isReadable()) {
// // this read should always succeed
// byte nextByte = buffer.readByte();
// if (nextByte == LF) {
// return sb.toString();
// } else {
// // Abort decoding if the decoded line is too large.
// if (sb.length() >= maxLineLength) {
// throw new TooLongFrameException(
// "ESL message line is longer than " + maxLineLength + " bytes.");
// }
// sb.append((char) nextByte);
// }
// }
List<Byte> bytes = new ArrayList<>();
while (buffer.isReadable()) {
// this read should always succeed
byte nextByte = buffer.readByte();
if (nextByte == LF) {
break;
} else {
// Abort decoding if the decoded line is too large.
if (sb.length() >= maxLineLength) {
throw new TooLongFrameException(
"ESL message line is longer than " + maxLineLength + " bytes.");
}
bytes.add(nextByte);
}
}
try {
String str = new String(Bytes.toArray(bytes), "UTF-8");
return str;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sb.toString();
}
}
Inbound mode.
This is my code:
`
String uuid = eslEvent.getEventHeaders().get("Unique-ID");
logger.warn("Creating execute app for uuid {" + uuid + "}");
Execute exe = new Execute(context, uuid);
try {
while (true) {
String result = exe.playAndDetectSpeech(Constant.AUDIO_PATH,"unimrcp",Constant.GRAMMAR_PATH);
logger.info("================" + result + "=================");
}
} catch (ExecuteException e) {
logger.error("Cound not detect speech");
} finally {
try {
exe.hangup();
} catch (ExecuteException e) {
logger.error("could not hang up");
}
}
`
But I get this:
Creating execute app for uuid {5afd66e5-c7e1-4bfd-b48d-cf7b426e1a41}
EslFrameDecoder - read header line [Content-Type: command/reply]
EslMessage - adding header [CONTENT_TYPE] [command/reply]
EslFrameDecoder - read header line [Reply-Text: -ERR invalid session id []]
EslMessage - adding header [REPLY_TEXT] [-ERR invalid session id []]
any help?
Find someone willing to take over this project. I do not work on telephony anymore and am not in a position to maintain this anymore.
Hi, We have tried using the library and experiencing this behaviour after few hours of traffic. Application doesn't crash and also re-connection to freeswitch works( Including Auth and Even subscription) However canSend()
is false
after all of these similar re-connections.
Jul 19 19:30:17 service: 2022-07-19T11:30:17.821+00:00||DEBUG|AbstractChannelHandlerContext ||||An exception java.lang.NullPointerException
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2086)
at org.freeswitch.esl.client.internal.AbstractEslClientHandler.exceptionCaught(AbstractEslClientHandler.java:74)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:302)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:281)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:273)
at io.netty.channel.DefaultChannelPipeline$HeadContext.exceptionCaught(DefaultChannelPipeline.java:1377)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:302)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:281)
at io.netty.channel.DefaultChannelPipeline.fireExceptionCaught(DefaultChannelPipeline.java:907)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.handleReadException(AbstractNioByteChannel.java:125)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:177)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Bits.java:175)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:118)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317)
at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:649)
at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:624)
at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:203)
at io.netty.buffer.PoolArena.tcacheAllocateNormal(PoolArena.java:187)
at io.netty.buffer.PoolArena.allocate(PoolArena.java:136)
at io.netty.buffer.PoolArena.allocate(PoolArena.java:126)
at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:396)
at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:188)
at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179)
at io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:140)
at io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:120)
at io.netty.channel.nio.AbstractNioByteChan
nel$NioByteUnsafe.read(AbstractNioByteChannel.java:150)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Few details to note.
Appreciate if someone can provide any insights on this.
netty version : 4.1.23
[2018-10-23 17:31:47.436]-[192.168.1.231]-[ERROR]-[nioEventLoopGroup-2-1]-[io.netty.util.ResourceLeakDetector]-[12456]-[Slf4JLogger.java:171]-[LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.Recent access records: #1: io.netty.buffer.AdvancedLeakAwareByteBuf.readByte(AdvancedLeakAwareByteBuf.java:400) org.freeswitch.esl.client.transport.message.EslFrameDecoder.readLine(EslFrameDecoder.java:184) org.freeswitch.esl.client.transport.message.EslFrameDecoder.decode(EslFrameDecoder.java:143) io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367) io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:748)#2: io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:604) io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:849) io.netty.buffer.WrappedByteBuf.readBytes(WrappedByteBuf.java:616) io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:473) io.netty.handler.codec.ReplayingDecoderByteBuf.readBytes(ReplayingDecoderByteBuf.java:577) org.freeswitch.esl.client.transport.message.EslFrameDecoder.decode(EslFrameDecoder.java:139) io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367) io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:748)Created at: io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:331) io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:185) io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:121) io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:848) io.netty.buffer.WrappedByteBuf.readBytes(WrappedByteBuf.java:616) io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:473) io.netty.handler.codec.ReplayingDecoderByteBuf.readBytes(ReplayingDecoderByteBuf.java:577) org.freeswitch.esl.client.transport.message.EslFrameDecoder.decode(EslFrameDecoder.java:139) io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367) io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:748): 44 leak records were discarded because they were duplicates: 44 leak records were discarded because the leak record count is targeted to 4. Use system property io.netty.leakDetection.targetRecords to increase the limit.]
Memory leak
[ERROR]-[Thread: nioEventLoopGroup-2-1]-[io.netty.util.internal.logging.Slf4JLogger.error(171)]: LEAK: ByteBuf.release() was not called before it’s garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
#1:
io.netty.buffer.AdvancedLeakAwareByteBuf.readByte(AdvancedLeakAwareByteBuf.java:400)
org.freeswitch.esl.client.transport.message.EslFrameDecoder.readLine(EslFrameDecoder.java:184)
org.freeswitch.esl.client.transport.message.EslFrameDecoder.decode(EslFrameDecoder.java:143)
io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367)
io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:138)
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
java.lang.Thread.run(Thread.java:745)
Created at:
io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:604)
io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:849)
io.netty.handler.codec.ReplayingDecoderByteBuf.readBytes(ReplayingDecoderByteBuf.java:577)
org.freeswitch.esl.client.transport.message.EslFrameDecoder.decode(EslFrameDecoder.java:139)
io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367)
io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:138)
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
java.lang.Thread.run(Thread.java:745)
: 4655 leak records were discarded because they were duplicates
: 4655 leak records were discarded because the leak record count is targeted to 4. Use system property io.netty.leakDetection.targetRecords to increase the limit.
Message decoder cannot correctly decode message with UTF-8 characters. I have patch, I will make a merge request.
compile 'io.netty:netty-all:4.0.27.Final'
compile 'com.google.guava:guava:11.0'
compile 'org.slf4j:slf4j-api:1.6.1'
runtime 'ch.qos.logback:logback-classic:1.0.0'
testCompile 'junit:junit:4.8.1'
当我利用freeswitch通讯一部电话后,怎么再接通后发送按键(DTMF)
this is an new esl api for freeswitch https://github.com/Tangwego/freeswitch-manager
Run to here:
final EslMessage response = getUnchecked(handler.sendApiMultiLineCommand(channel, sendMsg.getMsgLines()));
The program is blocked。
FreeSWITCH Version 1.4.23+git20151012T220044Zf90dd4b1c0~64bit
Netty log:
18:39:54.378 [nioEventLoopGroup-1-0] WARN o.freeswitch.esl.client.OutboundTest - Creating execute app for uuid 281195b0-3b00-4eb3-8eca-e90763abc103
18:39:54.381 [nioEventLoopGroup-1-0] DEBUG i.n.handler.logging.LoggingHandler - [id: 0x64eba323, /127.0.0.1:61978 => /127.0.0.1:8084] WRITE: 56B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 73 65 6e 64 6d 73 67 0a 63 61 6c 6c 2d 63 6f 6d |sendmsg.call-com|
|00000010| 6d 61 6e 64 3a 20 65 78 65 63 75 74 65 0a 65 78 |mand: execute.ex|
|00000020| 65 63 75 74 65 2d 61 70 70 2d 6e 61 6d 65 3a 20 |ecute-app-name: |
|00000030| 61 6e 73 77 65 72 0a 0a |answer.. |
+--------+-------------------------------------------------+----------------+
answer message no FLUSH to IO
Are there any plans for a release on Maven Central? IMHO, that would make using this fork much easier.
Possible issues:
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.