[client-side code](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++/client.cpp) of echo.
# Quick facts
- Channel.Init() is not thread-safe.
- Channel.CallMethod() is thread-safe and a Channel can be unused by multiple threads simultaneously.
- Channel can be allocated on stack.
- Channel can be destructed after sending asynchronous request.
- No class named brpc::Client.
# Channel
Client-side is the one sending requests, it's called [brpc::Channel](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/channel.h) rather "Client" in brpc. A channel may represent the communication line to one server or multiple servers, which can be used to call that Server's services.
A Channel can be **shared by all threads**. Yon don't need to create separate Channel for each thread, and you don't need to protect Channel.CallMethod with lock. But creation/Init/destroying of Channel is **not** thread-safe, make sure the channel is initialized and destroyed only by one thread.
Some RPC implementations have so-called "ClientManager", including configurations and resource management of the client-side, which is not needed by brpc. "thread-num", "connection-type" put in "ClientManager" are supported either via brpc::ChannelOptions or a global gflag. Advantages of doing so:
1. Convenience. You don't have to pass in a "ClientManager" when the Channel is created, and you don't have to store the "ClientManager". Otherwise many code have to pass "ClientManager" layer by layer, which is troublesome. gflags makes configurations of some global behaviors easier.
2. Share resources. For example, server and channel share background threads. (workers of bthread)
3. Better management of Lifetime. Destructing a "ClientManager" is very error-prone, which is managed by brpc right now.
Like most classes, Channel must be **Init()**-ed before usage. Parameters take default values when options is NULL. If you want to use non-default values, just code as follows:
```c++
brpc::ChannelOptionsoptions;// including default values
options.xxx=yyy;
...
channel.Init(...,&options);
```
Note that Channel does not modify `options` and not access `options` when Init() is complete, thus options is put on stack generally as in above code.
Init() can connect one server or multiple servers(a cluster).
The server connected by these Init() has fixed IP address genrally. The creation does not need NamingService and LoadBalancer, being relatively light-weight. Don't frequently create Channels connecting to a hostname, which requires a DNS lookup and may take at most 10 seconds. (the default timeout of DNS lookup).
| idle_timeout_second | 10 | Pooled connections without data transmission for so many seconds will be closed. No effect for non-positive values | src/brpc/socket_map.cpp |
| log_idle_connection_close | false | Print log when an idle connection is closed | src/brpc/socket.cpp |
| defer_close_second | 0 | Defer close of connections for so many seconds even if the connection is not used by anyone. Close immediately for non-positive values | src/brpc/socket_map.cpp |
FATAL 04-07 20:00:03 7778 public/brpc/src/brpc/channel.cpp:123] Invalid address=`bns://group.user-persona.dumi.nj03'. You should use Init(naming_service_name, load_balancer_name, options) to access multiple servers.