青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

libjingle Important Concepts

轉載自:https://developers.google.com/talk/libjingle/important_concepts?hl=zh-CN

Important Concepts

You should understand the following important concepts about libjingle:

Signals

libjingle uses the sigslot library to facilitate communication between objects. sigslot is a generic framework that enables you to connect a calling member to a receiving function in any class (including the same class) very simply. The way it works is this:

  1. The sending class declares a member variable, called a signal, using a special template-like syntax. This signal defines the parameters of the listening function.
  2. The listening class implements a function with the same number, type, and sequence of parameters as the signal. This is sometimes called the receiver or the slot. (Note: this can even be the same class as the one that declared the signal.) This function cannot return a value (e.g., returns void). The receiver must inheritsigslot::has_slots<>.
  3. The listener connects to the signal by calling the signal's connect method, passing in a pointer to the instance of the listening object, and the address of the implementing class function.
  4. The sender calls its signal member as if it were a function, passing in the appropriate parameter types as declared. It can pass parameters by either value or reference.

You can connect as many signals as you like to a common slot. libjingle sometimes assigns multiple signals to a single slot in order to consolidate its message handling. Conversely, several objects declare a signal object in order to broadcast commonly needed messages from a single point (for example, alerts sent when a connection state changes). sigslot takes care of disconnecting callbacks and dereferencing when objects are destroyed.

The following code demonstrates using sigslot:

// Class that sends the notification.
class Sender  {

  // The signal declaration. 
  // The '2' in the name indicates the number of parameters. Parameter types 
  // are declared in the template parameter list.
  sigslot::signal2<string message, std::time_t time> SignalDanger;

  // When anyone calls Panic(), we will send the SignalDanger signal.
  void Panic(){
    SignalDanger("Help!", std::time(0)); 
  }
 
 // Listening class. It must inherit sigslot.
class Receiver : public sigslot::has_slots<>{

  // Receiver registers to get SignalDanger signals.
  // When SignalDanger is sent, it is caught by OnDanger().
  // Second parameter gives address of the listener function class definition.
  // First parameter points to instance of this class to receive notifications.
  Receiver(Sender sender){ 
        sender->SignalDanger.connect(this, &Receiver.OnDanger);
  }

  // When anyone calls Panic(), Receiver::OnDanger gets the message.
  // Notice that the number and type of parameters match
  // those in Sender::SignalDanger, and that it doesn't return a value.
  void OnDanger(string message, std::time_t time){
    if(message == "Help!")
    { 
      // Call the police
      ...
    }
  }
...
}

Many classes in the code send signals to notify listeners of important events. For example, Call::SignalSessionState sends notifications when you send or receive a connection attempt. Your application must connect to these signals and act appropriately.

The general convention in libjingle code is to prefix the name of a signal with Signal: e.g., SignalStateChange, SignalSessionState, SignalSessionCreate. Listener methods intended to connect to signals are typically prefixed with On, e.g., OnPortDestroyed(), OnOutgoingMessage(), OnSendPacket().

See the sigslot documentation for more details.

Threads

libjingle supports multithreading in order to improve the performance of your application. libjingle components use one or two globally available threads:

  • The signaling thread is the thread used to create all the basic components, such as the Session Management and Control and XMPP Messaging components.
  • The worker thread (sometimes called the channel thread in the code) is used by the Peer to Peer component objects to handle more resource intensive processes, such as data streaming. Putting these on a separate thread prevents data flow from blocking or being blocked by XMPP or user interface components. Classes using the worker thread include ChannelManager, SocketMonitor, P2PTransportChannel, and the Port objects. To enable a second thread, you must create and pass a new Threadobject to the SessionManager constructor. (If no thread is passed in, the thread in which SessionManager was created will be used as the worker thread).CallClient::InitPhone demonstrates creating a worker thread for the low-level components.

Additionally, libjingle now provides a base class called SignalThread. Extend this class to enable an object that exists on its own thread, and which can be instantiated, started, and left alone to complete and delete itself when done. See signalthread.h/.cc for more information.

Note:   Although libjingle supports multiple threads, only certain methods support thread safety by verifying the calling thread, and very few methods do any locking. The following snippet demonstrates how a method verifies which thread it is being called on:

// Check that we're being called from the channel (e.g., worker) thread.
ASSERT(talk_base::Thread::Current() == channel_thread_);
channel_thread_->Clear(this);

libjingle wraps all threads, the signaling thread, the worker thread, and any other threads, with the talk_base::Thread object (or a derived object). All Thread objects are managed by ThreadManager, which retrieves them on request. SessionManager calls ThreadManager::CurrentThread to provide it with a signaling thread (and a worker thread, if none is provided) when it is instantiated; XmppPump uses the current thread for its signaling thread. Therefore, you must create a Thread object (or derived object) for the signaling thread and push it into ThreadManager's thread pool before creating a SessionManager object, or before expecting the XmppPump to start working. (See Signing In to a Serverfor example code.) There are two ways to create a Thread:

  • AutoThread   This wraps the existing operating system thread with a libjingle Thread object and makes it the current thread in the ThreadManager object's thread pool (that is, will return the thread if Thread::CurrentThread is called).
  • Thread   This creates and wraps a new thread to use, typically for a worker thread. In order to use this thread, you have to create a new Thread object, callThreadManager::Add or ThreadManager::SetCurrent to add it to the pool, and call Run to start it in a blocking loop, or Start to start the thread listening.

Threads provide a conduit for messages between (or within) objects. For instance, SocketManager sends a message to itself on another thread to destroy a socket, or toSessionManager when connection candidates have been generated. The Thread object inherits MessageQueue, and together they expose Send, Post, and other methods for sending messages synchronously and asynchronously. An object that will receive messages sent using MessageQueue must inherit and implement MessageHandler.MessageHandler defines the OnMessage method, which is called with the MessageQueue messages.

You can send messages to any object that inherits talk_base::MessageHandler over any thread. However, if sending a message to perform a resource-intensive thread, you should send the message over the worker thread. You can get a handle to the worker thread by calling SessionManager::worker_thread(). You can get a handle to the signaling thread by calling SessionManager::signaling_thread().

An object has several ways to access a specific thread: it can request and store a thread pointer as an input parameter; it can assume that the current thread when it is created (accessed by ThreadManager::CurrentThread in its constructor) is a particular thread and cache a member pointer to it; it can call SessionManger::signal_thread() orSessionManager::worker_thread() to retrieve threads. All three techniques are used in libjingle.

Because an object can be called on any thread, an object may need to verify which thread a method is being called from. To do this, call Thread::Current (which retrieves the current thread) and compare that value against a known thread--this can be one of the threads exposed by SessionManager, or the object can store a pointer to its initial thread in the constructor. Here is a more extended example of calling a method in the same object on another thread.

// Note that worker_thread_ is not initialized until someone 
// calls PseudoTcpChannel::Connect
// Also note that this method *is* thread-safe. 
bool PseudoTcpChannel::Connect(const std::string& channel_name) {
  ASSERT(signal_thread_->IsCurrent());
  CritScope lock(&cs_);
    if (channel_)
      return false;
    ASSERT(session_ != NULL);
    worker_thread_ = session_->session_manager()->worker_thread();
...
}

void PseudoTcpChannel::SomeFunction(){
  ...
  // Post a message to yourself over the worker thread.
  worker_thread_->Post(this, MSG_PING); // <- Goes in here....
  ...
}

// Handle queued requests.
void PseudoTcpChannel::OnMessage(Message *pmsg) {
  if (pmsg->message_id == MSG_SORT)
    OnSort();
  else if (pmsg->message_id == MSG_PING) // -> And comes out here!
    // Check that we're in the worker thread before proceding.
    ASSERT(worker_thread_->IsCurrent());
    OnPing();
  else if (pmsg->message_id == MSG_ALLOCATE)
    OnAllocate();
  else
    assert(false);
}

Naming Conventions

libjingle has some naming conventions that it is useful to be aware of:

  • OnSomeMethod   Methods beginning with "On" are often connected to a signal, either from this or another object. If called from the same object, it is probably called on a different thread.
  • SomeMethod_w   Methods ending with "_w" exist in the "worker thread" and are called from another thread
  • SignalSomeName   These are the signals that send messages to callback methods.

SSL Support

libjingle supports two types of SSL:

  • OpenSSL (for UNIX)
  • SChannel (for Windows)

To use SSL, you must perform the following steps:

  1. #define FEATURE_ENABLE_SSL (in the Visual Studio project, this value is defined in the project settings, not in the code).
  2. Ensure that either SSL_USE_OPENSSL or SSL_USE_SCHANNEL are #defined in ssladapter.cc. One of these should be defined by default, depending on the build settings for your operating system.
  3. Call InitializeSSL to initialize required components. This function is defined in ssladapter.cc. When the application closes down, call CleanupSSL. You do not need to call InitializeSSLThread (it is used internally by InitializeSSL).

Connections

A libjingle peer-to-peer connection actually consists of two channels:

  • The session negotiation channel (also called the signaling channel) is the communication link used to negotiate the data connection. This channel is used to request a connection, exchange candidates, and negotiate the details of the session (such as socket addresses, codecs needed, files to be exchanged, connection change requests, and termination requests). This is the first connection made between computers, and only after this connection is made can the data channel be established. libjingle uses a precursor to Jingle to specify the stanzas and responses needed to establish the data connection (see Jingle and libjingle) This channel sends stanzas through an intermediary XMPP server; the example code uses the Google Talk server as the intermediary.
  • The data channel carries the actual data (audio, video, files, etc) exchanged in the peer-to-peer session. Data channel data is wrapped in TCP or UDP packets, depending on the transport negotiated, and does not go through the XMPP server.

The session negotiation channel is established first, as the computers negotiate the details of the data channel; after the data connection is made, most activity occurs on the data channel, except for the occasional requests for a codec change, a new file request, a redirect request, or a termination request.

The following diagram shows these two pathways. In the diagram, two alternate data paths are shown, although only one data pathway will be active in a connection. This is because the data pathway can be either a direct connection (92% of connection attempts can take place directly) or through a relay server (8% of connection attempts require an intermediary relay server). A third data pathway, not shown, is a direct connection from computer to computer when there is no intermediary firewall.

Data exchange between two libjingle computers.

Notes:

  • libjingle sends out occasional STUN packets to maintain writability, keep firewall and NAT address bindings active, and check connection latency.
  • libjingle assigns a user name and password to connection ports. This ensures that the computer connecting on the data channel is the same one that negotiated the connection over the signaling channel. Because these username and password values are sent over XMPP and may or may not be encrypted with TLS, these values in a STUN packet are used only for identification, not cryptographic authentication.

To see the actual stanzas being sent, run the file share sample application.

Transports, Channels, and Connections

Each P2PTransportChannel represents a data channel between the local and remote computers. This channel actually obscures a complex system designed for robustness and performance. P2PTransportChannel manages a number of different Connection objects, each of which is specialized for a different connection type (UDP, TCP, etc). AConnection object actually wraps a pair of objects: a Port subclass, representing the local connection; and an address representing the remote connection. If a particular connection fails, P2PTransportChannel will seamlessly switch to the next best connection.

The following diagram shows a high level view of the data pathway inside the Peer to Peer Component.

The connection between Ports and Sockets.

When a libjingle application negotiates a connection with a remote computer, it creates a list of potential connection points, called candidates, on the local computer. Local candidates wrapped by Port objects, which are allocated by the PortAllocator subclass. Local Port objects are created by the offering computer before it sends out the offer, or by the receiving computer when it gets the request (if it hasn't already generated a list of local ports for any other reason). When P2PTransportChannel receives a connection offer from another computer (which includes the remote candidates), it creates one Connection object to wrap each remote candidate/local Port pair.

libjingle also defines a class named RawTransport that supports direct connections between two UDP connections, without using ICE. This transport would be used when you can create a direct UDP connection, or if one of the parties doesn't understand the ICE mechanism.

P2PTransportChannel creates and manages multiple connection objects. It evaluates them by writability and preference (UDP has a higher preference than a relay port connection, for example), and selects the best one to use. This may change as connections are broken or performance changes, but P2PTransportChannel switches connections seamlessly and invisibly to any classes higher up the chain.

P2PTransport (not shown) is the top-level creation and management object for the P2P data system. It creates and destroys the P2PTransportChannel, and monitors its general performance, but does not actually handle data; the true entry point for the data pipeline is P2PTransportChannel. VoiceChannel and PseudoTcpChannel connect toP2PTransportChannel to read and write their data.

The Session object hosts the P2PTransport object and requests creation of data channels. Although the Session object can potentially host multiple instances and subclasses ofTransport objects, the current version of the code only defines and uses one instance of the P2PTransport subclass.

Candidates

One of libjingle's key benefits is its ability to negotiate connections across firewalls or Network Address Translation (NAT)-enabled devices. libjingle uses the Interactive Connectivity Establishment (ICE) procedure to connect through a firewall. The first step a libjingle application does when trying to negotiate a connection is to generate a list of potential local port addresses for the other computer to connect to. Each of these potential addresses is called a candidate. Candidates are IP:port pairs to which both the application and the other computer can connect (technically, it only listens on the local connection). libjingle provides a robust mechanism for discovering valid local connection candidates that other computers can access, even through NAT devices or firewalls.

In order to provide as many potential connection addresses as possible to the other computer, libjingle generates three kinds of local candidates:

  • Local IP addresses   One candidate is a local IP addresses on the computer. Other computers sharing the same local network should be able to access this address.
  • Global addresses   A second candidate is an external address on a NAT or firewall device between the two computers. If this is outside a NAT device, libjingle uses STUN to cause the NAT to bind to your computer and expose a global address. This address is used as a candidate to connect from outside the NAT device.
  • Relay server addresses   Approximately 8% of clients attempting to connect across a firewall cannot make contact through either of the previous methods. A third method of connecting is through a relay server, a free-standing server that lives in the network space between the two firewalls. Although libjingle is capable of using a relay server, no relay server URI is provided. However, libjingle includes code for a relay server (relayserver.h/cc). You can build and run this server yourself, and use its IP address as the third parameter in the BasicPortAllocator constructor.

The following diagram shows two computers generating local address candidates (C1), external NAT candidates (C2), and Relay server candidates (C3).

Candidate selection diagram

libjingle stores the full list of potential candidates so that even after a connection is made, it can quickly switch to a new connection if the current connection slows down or breaks.

libjingle now includes support for multiple transports, in the spirit of the Jingle <transport> element. A transport can contain much more information than a simple candidate address: for example, the ICE transport tag supports ICE-specific information such as priority, password, and user fragments. Although this is the preferred way to negotiate connections, for backward compatibility purposes libjingle still supports clients that still use the older bare <candidate> stanza. See the Jingle ICE Transport Specification for an example of a transport specification.

Data Packets

Peer to peer data sent between computers can be wrapped in multiple layers of protocols, as shown here, depending on the application:

libjingle wraps data inside many nested packets.

Not all applications use all layers: for instance, the file share application uses pseudo-tcp, but the voice chat application does not.

posted on 2013-09-02 00:16 楊粼波 閱讀(876) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线视频日韩| 日韩一区二区久久| 在线观看成人网| 国产三级精品三级| 国产精品色在线| 国产精品九九| 国产精品一区二区三区四区| 欧美色图天堂网| 国产精品免费区二区三区观看| 欧美日韩亚洲另类| 国产精品综合色区在线观看| 国产午夜精品久久久| 国产精品亚洲一区二区三区在线| 欧美激情视频给我| 国产精品a久久久久| 国产日韩精品电影| 亚洲成人在线网| 亚洲一区3d动漫同人无遮挡| 欧美亚洲一区二区在线观看| 久久xxxx| 日韩视频在线观看一区二区| 午夜精品久久久久久久男人的天堂| 亚洲欧美影音先锋| 欧美高清不卡| 激情成人在线视频| 亚洲午夜精品久久久久久浪潮| 久久精品国产亚洲一区二区| 欧美激情片在线观看| 午夜国产精品视频免费体验区| 老牛国产精品一区的观看方式| 欧美破处大片在线视频| 黄色成人在线网站| 亚洲欧美另类在线| 一本色道久久综合亚洲精品不卡| 久久综合国产精品| 在线精品国产欧美| 久久婷婷麻豆| 久久亚洲风情| 亚洲人成高清| 亚洲美女视频在线观看| 欧美99在线视频观看| 亚洲国产成人porn| 欧美黄污视频| 欧美激情一区二区三区全黄| 亚洲国产一区二区视频| 亚洲激情视频网站| 老牛嫩草一区二区三区日本| 亚洲国产精品久久久久久女王| 久久午夜精品一区二区| 欧美在线观看视频在线 | 亚洲欧美在线网| 99热精品在线观看| 国产一区日韩二区欧美三区| 久久在线免费观看视频| 模特精品裸拍一区| 亚洲欧美日韩专区| 久久在线免费观看| 性欧美videos另类喷潮| 葵司免费一区二区三区四区五区| 一区二区三区日韩精品| 午夜精彩国产免费不卡不顿大片| 亚洲国产成人久久综合| 亚洲视频一区在线观看| 亚洲激情av| 久久精品国产久精国产爱| aⅴ色国产欧美| 久久综合伊人77777麻豆| 久久不射电影网| 国产精品乱码妇女bbbb| 亚洲国产成人高清精品| 韩国av一区二区三区在线观看| 亚洲三级毛片| 亚洲国产成人精品女人久久久| 亚洲综合欧美日韩| 亚洲欧美国产精品专区久久| 欧美日韩一区二区欧美激情| 亚洲欧洲日产国码二区| 亚洲第一天堂av| 玖玖玖国产精品| 久久久亚洲国产天美传媒修理工 | 久久亚洲私人国产精品va| 一区二区三区高清| 国产精品福利av| 亚洲一区在线免费观看| 亚洲视频在线观看| 国产精品va在线| 欧美一区二区三区精品| 亚洲在线观看免费| 狠狠干成人综合网| 欧美多人爱爱视频网站| 99riav久久精品riav| 欧美在线短视频| 在线免费观看成人网| 欧美日韩国产亚洲一区| 午夜一区不卡| 亚洲乱码国产乱码精品精| 先锋a资源在线看亚洲| 精品88久久久久88久久久| 欧美日韩一区二区在线视频| 午夜精品国产精品大乳美女| 亚洲成人在线网| 久久久美女艺术照精彩视频福利播放| 伊人成人在线视频| 欧美日韩免费在线| 美女黄网久久| 欧美主播一区二区三区美女 久久精品人 | 久久人人超碰| 黄色亚洲在线| 国产精品久久久久一区| 久久青草欧美一区二区三区| 亚洲精品一区二区三区不| 亚洲欧洲av一区二区| 亚洲精品国产精品国自产在线| 欧美久久久久免费| 亚洲一区视频在线观看视频| 亚洲激情小视频| 亚洲精品一区中文| 亚洲精品一区二| 99热精品在线| 欧美一区二区三区精品电影| 欧美怡红院视频| 欧美一区二区三区视频免费播放 | 免费日韩成人| 久久综合中文色婷婷| 免费亚洲一区二区| 欧美成人激情视频| 亚洲伦理网站| 性欧美18~19sex高清播放| 久久久久久免费| 国产精品欧美风情| 一区精品久久| 亚洲欧美视频在线观看| 蜜臀久久99精品久久久久久9| 亚洲欧洲日本mm| 午夜精品短视频| 欧美精品一二三| 狠狠色2019综合网| 正在播放亚洲| 亚洲风情亚aⅴ在线发布| 一区二区三区欧美亚洲| 久久深夜福利| 国产亚洲精品bt天堂精选| 亚洲国产欧美一区| 久久久久九九九九| 亚洲视频欧洲视频| 欧美精品一区二区三| 在线看片第一页欧美| 欧美亚洲免费电影| 一本色道久久88精品综合| 麻豆国产va免费精品高清在线| 国产精品自拍在线| 欧美有码视频| 午夜精品99久久免费| 好男人免费精品视频| 中文av一区特黄| 99国产精品久久久久久久| 欧美一区二区日韩| 国产伦精品一区二区| 亚洲在线一区二区| 亚洲一区二区三区免费在线观看 | 欧美日韩三级一区二区| 99爱精品视频| 亚洲女人av| 在线免费高清一区二区三区| 免费在线成人av| 欧美精品一区二区三区久久久竹菊| 一本色道久久综合亚洲精品婷婷 | 亚洲电影自拍| 欧美日韩精品免费观看| 亚洲曰本av电影| 欧美亚洲专区| 日韩视频精品| 午夜精品亚洲| 亚洲每日更新| 每日更新成人在线视频| 亚洲永久字幕| 欧美国产激情| 久久在线免费观看视频| 欧美日韩视频在线第一区| 久久久www免费人成黑人精品 | 国产亚洲二区| 99亚洲视频| 一本色道久久综合精品竹菊| 久久久久久网址| 欧美一区二区视频免费观看| 免费不卡在线观看av| 欧美一区2区视频在线观看| 麻豆久久婷婷| 欧美亚洲视频| 欧美色欧美亚洲高清在线视频| 久久久xxx| 国产麻豆午夜三级精品| 一区二区免费在线播放| 亚洲成人直播| 久久久五月天| 亚洲综合视频在线| 国产精品视频第一区| 亚洲精品乱码久久久久| 亚洲国产日韩美| 久久精品亚洲一区二区|