📄 sharecontent.cs
字号:
namespace Imps.Client.Core
{
using Imps.Base.Sipc;
using Imps.Client.Base;
using Imps.Client.Core.P2P.FileTransportor;
using Imps.Client.Core.P2P.ICE;
using Imps.Client.Resource;
using Imps.Client.Utils;
using Imps.Utils;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
public abstract class ShareContent : UserItemBase
{
private AsyncBizOperation _bizOperation;
private bool _complete;
private Dialog _dialog;
private string _downLoadUrl;
private string _fileName;
private string _filePath;
private long _fileSize;
private float _finishPercent;
private string _first100MMd5;
private string _id;
private bool _isCancel;
private bool _isClosed;
private bool _isFailed;
private long _lastCompleteSize;
private AllEndPoints _myEndPoints;
private OtherSideOption _otherSideOption;
private bool _p2pFailedToRelay;
private P2PSessionFinder _p2pFinder;
private IFileTransportor _p2pTransport;
private Peer _peer;
private string _previewImageBase64String;
private Imps.Client.Core.P2P.ICE.PunchingResult _punchingResult;
private float _rate;
private string _sessionId;
private bool _start;
private DateTime _startTime;
protected Socket _tcpListener;
protected Socket _tcpP2PSocket;
private ShareContentTransmitType _transmittype;
private Imps.Client.Core.P2P.FileTransportor.TransportingFile _transportingFile;
private int _tryCount;
internal int _tryInterval;
private AutoResetEvent _waitEvent;
public event EventHandler Closed;
public event EventHandler ShareContentCancel;
public event EventHandler ShareContentComplete;
public event EventHandler<ShareContentFailedEventArgs> ShareContentFailed;
public event EventHandler<ShareContentProcessEventArgs> ShareContentProgress;
public ShareContent(string filePath, Imps.Client.Core.User owner) : this(Guid.NewGuid(), filePath, owner)
{
}
public ShareContent(Guid id, string filePath, Imps.Client.Core.User owner) : base(owner)
{
this._tryInterval = 500;
this._tryCount = 5;
this._id = id.ToString("D");
P2PManager.Instace.LanPeerListener.AddShareContent(id, this);
this._filePath = filePath;
this._rate = 0f;
this._startTime = DateTime.Now;
this._waitEvent = new AutoResetEvent(false);
this._waitEvent.Set();
}
private void _p2pTransport_BlockTransported(object sender, BlockTranEventArgs e)
{
this.OnBlockTransported(e);
}
private void _p2pTransport_TransportCompleted(object sender, EventArgs e)
{
try
{
this.Complete = true;
this.RaiseShareContentComplete();
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
}
private void _p2pTransport_TransportFailed(object sender, TranFailedEventArgs e)
{
this.OnTransportFailed();
}
internal void AsyncSendCancelInfo()
{
XmlHelper.WriteXmlContentDelegate writeContentCallback = null;
try
{
SipRequest msg = this.CurrentDialog.InnerCreateSipRequest("IN", this.CurrentDialog.CallId, this.CurrentDialog.NextCSeq);
msg.Message.AddHeader(new SipcToHeader(this.CurrentDialog.To));
StringWriter tw = new StringWriter();
if (writeContentCallback == null)
{
writeContentCallback = delegate (XmlWriter writer, object context) {
writer.WriteAttributeString("action", "cancel");
writer.WriteStartElement("file");
writer.WriteAttributeString("url", this.DownLoadUrl);
writer.WriteAttributeString("id", this.Id);
writer.WriteEndElement();
};
}
XmlHelper.CreateXmlWriterForSipMessage(tw, null, writeContentCallback, "share-content");
msg.Message.Body = tw.ToString();
base.SendSipMessage(msg);
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
}
internal virtual void AsyncStartP2P()
{
}
public virtual void CancelShareContent()
{
}
public virtual void Close()
{
try
{
P2PManager.Instace.LanPeerListener.RemoveShareContent(new Guid(this.Id));
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
try
{
if ((this.Transmittype == ShareContentTransmitType.P2P) && (this.P2pTransport != null))
{
this.P2pTransport.Stop();
}
}
catch (Exception exception2)
{
ClientLogger.WriteException(exception2);
}
if (!this.IsClosed)
{
this.IsClosed = true;
if ((!this.IsCancel && !this.Complete) && !this.IsFailed)
{
this.CancelShareContent();
}
if (this.CurrentDialog != null)
{
this.CurrentDialog.ShareContents.Remove(this);
}
this.RaiseClosed();
if (this._waitEvent != null)
{
this._waitEvent.Close();
}
if (!this.Complete && (this._dialog != null))
{
this.SaveFailedHistory();
}
}
}
internal void CloseTcpListener()
{
if (this._tcpListener != null)
{
try
{
this._tcpListener.Close();
}
catch
{
}
}
}
public virtual void DoReceiveCancelInfo()
{
this.CancelShareContent();
}
internal ShareContentMessage GetShareContentMessage(string message)
{
ShareContentMessage message2 = new ShareContentMessage(this._dialog, message, "", "", true);
message2.Context = this;
return message2;
}
public static string GetTransmitType(ShareContentTransmitType type)
{
return Enum.GetName(typeof(ShareContentTransmitType), type).ToLower();
}
internal void InitTcpListener()
{
this._tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._tcpListener.Bind(new IPEndPoint(IPAddress.Any, 0));
this._tcpListener.Listen(10);
}
protected virtual void OnBlockTransported(BlockTranEventArgs e)
{
try
{
this.FinishPercent = ((float) e.Current) / ((float) e.Total);
this.RaiseShareContentProgress(new ShareContentProcessEventArgs(this.FinishPercent));
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
}
protected virtual void OnTransportFailed()
{
try
{
this.IsFailed = true;
this.RaiseShareContentFailed("");
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
}
internal void RaiseClosed()
{
if (this.Closed != null)
{
FuncDispatcher.InvokeEventHandlerInUiThread(this, this.Closed, EventArgs.Empty);
}
}
internal void RaiseShareContentCancel()
{
if (this.ShareContentCancel != null)
{
if (this._dialog != null)
{
ShareContentMessage msg = this.GetShareContentMessage(string.Format(StringTable.Conversation.MsgShareContentCancel, this.FileName));
msg.IsFailed = true;
this.RaiseShareContentMessage(msg);
}
FuncDispatcher.InvokeEventHandlerInUiThread(this, this.ShareContentCancel, EventArgs.Empty);
}
}
internal void RaiseShareContentComplete()
{
if (this.ShareContentComplete != null)
{
if (this._dialog != null)
{
ShareContentMessage msg = this.GetShareContentMessage(string.Format(StringTable.Conversation.MsgShareContentComplete, this.FileName));
if (this is DownLoadShareContent)
{
msg.IsDownloadComplete = true;
}
this.RaiseShareContentMessage(msg);
Thread.Sleep(50);
}
FuncDispatcher.InvokeEventHandlerInUiThread(this, this.ShareContentComplete, EventArgs.Empty);
}
this.Close();
}
internal void RaiseShareContentFailed(string error)
{
if (!this.IsFailed)
{
this.IsFailed = true;
if (this.ShareContentFailed != null)
{
if (this._dialog != null)
{
ShareContentMessage msg = this.GetShareContentMessage(string.Format(StringTable.Conversation.MsgShareContentFailed, this.FileName, error));
msg.IsFailed = true;
this.RaiseShareContentMessage(msg);
}
FuncDispatcher.InvokeEventHandlerInUiThread<ShareContentFailedEventArgs>(this, this.ShareContentFailed, new ShareContentFailedEventArgs(error));
}
}
this.Close();
}
internal void RaiseShareContentMessage(ShareContentMessage msg)
{
this._dialog.RaiseMessageReceived(new MessageEventArgs(msg));
}
internal void RaiseShareContentMessage(string message)
{
this.RaiseShareContentMessage(this.GetShareContentMessage(message));
}
internal void RaiseShareContentProgress(ShareContentProcessEventArgs e)
{
if (this.ShareContentProgress != null)
{
FuncDispatcher.InvokeEventHandlerInUiThread<ShareContentProcessEventArgs>(this, this.ShareContentProgress, e);
}
}
public virtual void RecordFinishEventForServer(string from, string to, string type)
{
HttpWebRequest request = ConnectionFactory.CreateHttpWebRequest(base.Owner.Configuration.SystemSetting.FileShareSetting.RecordFinishUri, base.Owner, false, true);
request.ContentType = "text/xml";
StringBuilder builder = new StringBuilder();
builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?><events>");
builder.Append(string.Format("<event type=\"{0}\">", type));
builder.Append(string.Format("<args sender=\"{0}\" receiver=\"{1}\" start-time=\"{2}\" end-time=\"{3}\" file-name=\"{4}\" file-size=\"{5}\" transmit-type=\"{6}\" client-type=\"{7}\"/>", new object[] { from, to, this._startTime.ToString("yyyy-MM-dd HH:mm:ss"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), this.FileName, this.FileSize, GetTransmitType(this.Transmittype), "PC" }));
builder.Append("</event></events>");
byte[] bytes = Encoding.UTF8.GetBytes(builder.ToString());
request.GetRequestStream().Write(bytes, 0, bytes.Length);
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
HttpStatusCode statusCode = response.StatusCode;
response.Close();
}
public void Resume()
{
try
{
this._waitEvent.Set();
}
catch
{
}
}
private void SaveFailedHistory()
{
if (!string.IsNullOrEmpty(this.FileName))
{
string from = "";
string fromUri = "";
if (this is DownLoadShareContent)
{
from = (this as DownLoadShareContent).From.DisplayName;
fromUri = (this as DownLoadShareContent).From.Uri.Raw;
}
else
{
from = base.Owner.Nickname;
fromUri = base.Owner.Uri.Raw;
}
ShareContentMessage message = new ShareContentMessage(this.CurrentDialog, string.Format("《{0}》发送失败!", this.FileName), from, fromUri, false);
message.IsFailed = true;
message.Time = Imps.Client.Core.User.ServerTime;
message.MessageType = MessageType.ImFile;
message.SaveMessage();
}
}
public void Wait()
{
try
{
this._waitEvent.Reset();
}
catch
{
}
}
public AsyncBizOperation BizOperation
{
get
{
return this._bizOperation;
}
set
{
this._bizOperation = value;
}
}
public bool Complete
{
get
{
return this._complete;
}
internal set
{
this._complete = value;
}
}
public Dialog CurrentDialog
{
get
{
return this._dialog;
}
internal set
{
this._dialog = value;
}
}
public string DownLoadUrl
{
get
{
return this._downLoadUrl;
}
internal set
{
this._downLoadUrl = value;
}
}
public int EveryBlockSize
{
get
{
if (this.Transmittype == ShareContentTransmitType.Relay)
{
return base.Owner.Configuration.SystemSetting.FileShareSetting.EveryBlockSizeWhenRelay;
}
return base.Owner.Configuration.SystemSetting.FileShareSetting.EveryBlockSizeWhenBlock;
}
}
public string FileName
{
get
{
return this._fileName;
}
internal set
{
this._fileName = value;
}
}
public string FilePath
{
get
{
return this._filePath;
}
set
{
this._filePath = value;
}
}
public long FileSize
{
get
{
return this._fileSize;
}
internal set
{
this._fileSize = value;
}
}
public float FinishPercent
{
get
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -