⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* * libjingle * Copyright 2004--2005, Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * *  1. Redistributions of source code must retain the above copyright notice, *     this list of conditions and the following disclaimer. *  2. Redistributions in binary form must reproduce the above copyright notice, *     this list of conditions and the following disclaimer in the documentation *     and/or other materials provided with the distribution. *  3. The name of the author may not be used to endorse or promote products *     derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "talk/p2p/base/session.h"#include "talk/base/common.h"#include "talk/base/logging.h"#include "talk/base/helpers.h"#include "talk/xmpp/constants.h"#include "talk/xmpp/jid.h"#include "talk/p2p/base/sessionclient.h"#include "talk/p2p/base/transport.h"#include "talk/p2p/base/transportchannelproxy.h"#include "talk/p2p/base/p2ptransport.h"#include "talk/p2p/base/constants.h"namespace {const uint32 MSG_TIMEOUT = 1;const uint32 MSG_ERROR = 2;const uint32 MSG_STATE = 3;// This will be initialized at run time to hold the list of default transports.std::string* gDefaultTransports = NULL;size_t gNumDefaultTransports = 0;}  // namespacenamespace cricket {Session::Session(SessionManager *session_manager, const std::string& name,                 const SessionID& id, const std::string& session_type,                 SessionClient* client) {  ASSERT(session_manager->signaling_thread()->IsCurrent());  ASSERT(client != NULL);  session_manager_ = session_manager;  name_ = name;  id_ = id;  session_type_ = session_type;  client_ = client;  error_ = ERROR_NONE;  state_ = STATE_INIT;  initiator_ = false;  description_ = NULL;  remote_description_ = NULL;  transport_ = NULL;  compatibility_mode_ = false;}Session::~Session() {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  ASSERT(state_ != STATE_DEINIT);  state_ = STATE_DEINIT;  SignalState(this, state_);  delete description_;  delete remote_description_;  for (ChannelMap::iterator iter = channels_.begin();       iter != channels_.end();       ++iter) {    iter->second->SignalDestroyed(iter->second);    delete iter->second;  }  for (TransportList::iterator iter = potential_transports_.begin();       iter != potential_transports_.end();       ++iter) {    delete *iter;  }  delete transport_;}bool Session::Initiate(const std::string &to,                       std::vector<buzz::XmlElement*>* extra_xml,                       const SessionDescription *description) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  // Only from STATE_INIT  if (state_ != STATE_INIT)    return false;  // Setup for signaling.  remote_name_ = to;  initiator_ = true;  description_ = description;  // Make sure we have transports to negotiate.  CreateTransports();  // Send the initiate message, including the application and transport offers.  XmlElements elems;  elems.push_back(client_->TranslateSessionDescription(description));  for (TransportList::iterator iter = potential_transports_.begin();       iter != potential_transports_.end();       ++iter) {    buzz::XmlElement* elem = (*iter)->CreateTransportOffer();    elems.push_back(elem);  }  if (extra_xml != NULL) {           std::vector<buzz::XmlElement*>::iterator iter = extra_xml->begin();    for (std::vector<buzz::XmlElement*>::iterator iter = extra_xml->begin();        iter != extra_xml->end();        ++iter) {      elems.push_back(new buzz::XmlElement(**iter));    }  }        SendSessionMessage("initiate", elems);  SetState(Session::STATE_SENTINITIATE);  // We speculatively start attempting connection of the P2P transports.  ConnectDefaultTransportChannels(true);  return true;}void Session::ConnectDefaultTransportChannels(bool create) {  Transport* transport = GetTransport(kNsP2pTransport);  if (transport) {    for (ChannelMap::iterator iter = channels_.begin();         iter != channels_.end();         ++iter) {      ASSERT(create != transport->HasChannel(iter->first));      if (create) {        transport->CreateChannel(iter->first, session_type());      }    }    transport->ConnectChannels();  }}void Session::CreateDefaultTransportChannel(const std::string& name) {  // This method is only relevant when we have created the default transport  // but not received a transport-accept.  ASSERT(transport_ == NULL);  ASSERT(state_ == STATE_SENTINITIATE);  Transport* p2p_transport = GetTransport(kNsP2pTransport);  if (p2p_transport) {    ASSERT(!p2p_transport->HasChannel(name));    p2p_transport->CreateChannel(name, session_type());  }}bool Session::Accept(const SessionDescription *description) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  // Only if just received initiate  if (state_ != STATE_RECEIVEDINITIATE)    return false;  // Setup for signaling.  initiator_ = false;  description_ = description;  // If we haven't selected a transport, wait for ChooseTransport to complete  if (transport_ == NULL)    return true;  // Send the accept message.  XmlElements elems;  elems.push_back(client_->TranslateSessionDescription(description_));  SendSessionMessage("accept", elems);  SetState(Session::STATE_SENTACCEPT);  return true;}bool Session::Reject() {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  // Reject is sent in response to an initiate or modify, to reject the  // request  if (state_ != STATE_RECEIVEDINITIATE && state_ != STATE_RECEIVEDMODIFY)    return false;  // Setup for signaling.  initiator_ = false;  // Send the reject message.  SendSessionMessage("reject", XmlElements());  SetState(STATE_SENTREJECT);  return true;}bool Session::Redirect(const std::string & target) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  // Redirect is sent in response to an initiate or modify, to redirect the  // request  if (state_ != STATE_RECEIVEDINITIATE)    return false;  // Setup for signaling.  initiator_ = false;  // Send a redirect message to the given target.  We include an element that  // names the redirector (us), which may be useful to the other side.  buzz::XmlElement* target_elem = new buzz::XmlElement(QN_REDIRECT_TARGET);  target_elem->AddAttr(buzz::QN_NAME, target);  buzz::XmlElement* cookie = new buzz::XmlElement(QN_REDIRECT_COOKIE);  buzz::XmlElement* regarding = new buzz::XmlElement(QN_REDIRECT_REGARDING);  regarding->AddAttr(buzz::QN_NAME, name_);  cookie->AddElement(regarding);  XmlElements elems;  elems.push_back(target_elem);  elems.push_back(cookie);  SendSessionMessage("redirect", elems);  // A redirect puts us in the same state as reject.  It just sends a different  // kind of reject message, if you like.  SetState(STATE_SENTREDIRECT);  return true;}bool Session::Terminate() {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  // Either side can terminate, at any time.  switch (state_) {    case STATE_SENTTERMINATE:    case STATE_RECEIVEDTERMINATE:      return false;    case STATE_SENTREDIRECT:      // We must not send terminate if we redirect.      break;    case STATE_SENTREJECT:    case STATE_RECEIVEDREJECT:      // We don't need to send terminate if we sent or received a reject...      // it's implicit.      break;    default:      SendSessionMessage("terminate", XmlElements());      break;  }  SetState(STATE_SENTTERMINATE);  return true;}void Session::SendInfoMessage(const XmlElements& elems) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  SendSessionMessage("info", elems);}void Session::SetPotentialTransports(const std::string names[], size_t length) {  ASSERT(session_manager_->signaling_thread()->IsCurrent());  for (size_t i = 0; i < length; ++i) {    Transport* transport = NULL;    if (names[i] == kNsP2pTransport) {      transport = new P2PTransport(session_manager_);    } else {      ASSERT(false);    }    if (transport) {      ASSERT(transport->name() == names[i]);      potential_transports_.push_back(transport);      transport->SignalConnecting.connect(          this, &Session::OnTransportConnecting);      transport->SignalWritableState.connect(          this, &Session::OnTransportWritable);      transport->SignalRequestSignaling.connect(          this, &Session::OnTransportRequestSignaling);      transport->SignalTransportMessage.connect(          this, &Session::OnTransportSendMessage);      transport->SignalTransportError.connect(          this, &Session::OnTransportSendError);      transport->SignalChannelGone.connect(          this, &Session::OnTransportChannelGone);    }  }}Transport* Session::GetTransport(const std::string& name) {  if (transport_ != NULL) {    if (name == transport_->name())      return transport_;  } else {    for (TransportList::iterator iter = potential_transports_.begin();        iter != potential_transports_.end();        ++iter) {      if (name == (*iter)->name())        return *iter;    }  }  return NULL;}TransportChannel* Session::CreateChannel(const std::string& name) {  //ASSERT(session_manager_->signaling_thread()->IsCurrent());  ASSERT(channels_.find(name) == channels_.end());  TransportChannelProxy* channel = new TransportChannelProxy(name, session_type_);  channels_[name] = channel;  if (transport_) {    ASSERT(!transport_->HasChannel(name));    channel->SetImplementation(transport_->CreateChannel(name, session_type_));  } else if (state_ == STATE_SENTINITIATE) {    // In this case, we have already speculatively created the default    // transport.  We should create this channel as well so that it may begin    // early connection.    CreateDefaultTransportChannel(name);  }  return channel;}TransportChannel* Session::GetChannel(const std::string& name) {  ChannelMap::iterator iter = channels_.find(name);  return (iter != channels_.end()) ? iter->second : NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -