当前位置:首页 » 《资源分享》 » 正文

xamarin.android 即时通讯 文件传输_cao19989的博客

20 人参与  2021年11月01日 10:03  分类 : 《资源分享》  评论

点击全文阅读


大家晚上好:
本期我们接着上次讲即时通讯服务端外加客户端文件传输

服务端

1.服务端的作用:

 我们在通信时不可能一对一直接连接到千里之外的另外一台手机

有众多原因 其一是: ip 不在同一网段,其二:每个手机地域限制影响
包括大家众所周知的QQ,微信 等 都是 通过 中转站 服务器(监听端程序)
服务器所处环境在公网,客户端可以直接通过公网IP连接,

2.客户端与客户端通讯:

注册账号是生成唯一ID,用作每个客户端的key 存储在服务端,客户端连接服务端后将key用作连接对象的key 存储在缓存中,
例如: 有两个客户端 A,B,一个服务端C
A发消息给B,
首先是获取服务端所存储的所有连接对象信息包括Key,加载到A本地
A指定B对象得到key 发送信息给服务端;
服务端C接收到信息 解析接收人的key ,在连接对象内存中去key的连接对象
把消息发送给B。
也就是上篇文章画的草图 :
在这里插入图片描述

下面展示服务端程序:
在这里插入图片描述

##下面是服务端代码
下面介绍下文件传输思路:
客户端把文件发送给服务端:服务端保存至IIS站点下:
将路径返回给接收消息的一端:
例如下面这张图片:就是测试所作的
前面的ip 是我个人的服务器公网地址
http://47.115.26.219:8099/mmexport1631624696079.jpg

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;
using Newtonsoft.Json;

namespace ChatServer
{
    public partial class FServer : Form
    {
        public FServer()
        {
            InitializeComponent();
            //关闭对文本框的非法线程操作检查
            TextBox.CheckForIllegalCrossThreadCalls = false;
        }
        //分别创建一个监听客户端的线程和套接字
        Thread threadWatch = null;
        Socket socketWatch = null;

        public const int SendBufferSize = 2 * 1024;
        public const int ReceiveBufferSize = 8 * 1024;

        private void btnStartService_Click(object sender, EventArgs e)
        {
            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //发送信息 需要1个IP地址和端口号
            //获取服务端IPv4地址
            IPAddress ipAddress = Dns.GetHostAddresses(Dns.GetHostName())[5];// GetLocalIPv4Address();
            lblIP.Text = ipAddress.ToString();
            //给服务端赋予一个端口号
            int port = 9000;
            lblPort.Text = port.ToString();

            //将IP地址和端口号绑定到网络节点endpoint上 
            IPEndPoint endpoint = new IPEndPoint(ipAddress, port);
            //将负责监听的套接字绑定网络端点
            socketWatch.Bind(endpoint);
            //将套接字的监听队列长度设置为20
            socketWatch.Listen(20);
            //创建一个负责监听客户端的线程 
            threadWatch = new Thread(WatchConnecting);
            //将窗体线程设置为与后台同步
            threadWatch.IsBackground = true;
            //启动线程
            threadWatch.Start();
            txtMsg.AppendText("服务器已经启动,开始监听客户端传来的信息!" + "\r\n");
            btnStartService.Enabled = false;
        }

        /// <summary>
        /// 获取本地IPv4地址
        /// </summary>
        /// <returns>本地IPv4地址</returns>
        public IPAddress GetLocalIPv4Address()
        {
            IPAddress localIPv4 = null;
            //获取本机所有的IP地址列表
            IPAddress[] ipAddressList = Dns.GetHostAddresses(Dns.GetHostName());
            foreach (IPAddress ipAddress in ipAddressList)
            {
                //判断是否是IPv4地址
                if (ipAddress.AddressFamily == AddressFamily.InterNetwork) //AddressFamily.InterNetwork表示IPv4 
                {
                    localIPv4 = ipAddress;
                    break;
                }
                else
                    continue;
            }
            return localIPv4;
        }

        //用于保存所有通信客户端的Socket
        Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

        //创建与客户端建立连接的套接字
        Socket socConnection = null;
        string clientName = null; //创建访问客户端的名字
        IPAddress clientIP; //访问客户端的IP
        int clientPort; //访问客户端的端口号
        /// <summary>
        /// 持续不断监听客户端发来的请求, 用于不断获取客户端发送过来的连续数据信息
        /// </summary>
        private void WatchConnecting()
        {
            while (true)
            {
                try
                {
                    socConnection = socketWatch.Accept();
                }
                catch (Exception ex)
                {
                    txtMsg.AppendText(ex.Message); //提示套接字监听异常
                    break;
                }
                //获取访问客户端的IP
                clientIP = (socConnection.RemoteEndPoint as IPEndPoint).Address;
                //获取访问客户端的Port
                clientPort = (socConnection.RemoteEndPoint as IPEndPoint).Port;
                //创建访问客户端的唯一标识 由IP和端口号组成 
                clientName = "IP: " + clientIP + " Port: " + clientPort;
                lstClients.Items.Add(clientName); //在客户端列表添加该访问客户端的唯一标识
                dicSocket.Add(clientName, socConnection); //将客户端名字和套接字添加到添加到数据字典中


                //创建通信线程 
                ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);
                Thread thread = new Thread(pts);
                thread.IsBackground = true;
                //启动线程
                thread.Start(socConnection);
                txtMsg.AppendText("IP: " + clientIP + " Port: " + clientPort + " 的客户端与您连接成功,现在你们可以开始通信了...\r\n");
            }
        }

        /// <summary>
        /// 发送信息到客户端的方法
        /// </summary>
        /// <param name="sendMsg">发送的字符串信息</param>
        private void ServerSendMsg(string sendMsg)
        {
            sendMsg = txtSendMsg.Text.Trim();
            //将输入的字符串转换成 机器可以识别的字节数组
            byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
            //向客户端列表选中的客户端发送信息
            if (!string.IsNullOrEmpty(lstClients.Text.Trim()))
            {
                //获得相应的套接字 并将字节数组信息发送出去
                dicSocket[lstClients.Text.Trim()].Send(arrSendMsg);
                //通过Socket的send方法将字节数组发送出去
                txtMsg.AppendText("您在 " + GetCurrentTime() + " 向 IP: " + clientIP + " Port: " + clientPort + " 的客户端发送了:\r\n" + sendMsg + "\r\n");
            }
            else //如果未选择任何客户端 则默认为群发信息
            {
                //遍历所有的客户端
                for (int i = 0; i < lstClients.Items.Count; i++)
                {
                    dicSocket[lstClients.Items[i].ToString()].Send(arrSendMsg);
                }
                txtMsg.AppendText("您在 " + GetCurrentTime() + " 群发了信息:\r\n" + sendMsg + " \r\n");
            }
        }

        string strSRecMsg = null;
        public ScokeSendFile sendFile = null;
        public bool IsHead = false;
        public string ReceiveUserID { get; set; }

        public string SendClientMsg { get; set; }
        /// <summary>
        /// 接收客户端发来的信息
        /// </summary>
        private void ServerRecMsg(object socketClientPara)
        {
            Socket socketServer = socketClientPara as Socket;

            long fileLength = 0;
            while (true)
            {
                int firstReceived = 0;
                byte[] buffer = new byte[ReceiveBufferSize];
                try
                {
                    //获取接收的数据,并存入内存缓冲区  返回一个字节数组的长度
                    if (socketServer != null) firstReceived = socketServer.Receive(buffer);

                    if (firstReceived > 0) //接受到的长度大于0 说明有信息或文件传来
                    {
                        if (buffer[0] == 0) //0为文字信息
                        {
                            strSRecMsg = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);//真实有用的文本信息要比接收到的少1(标识符)
                            var Mymsg = strSRecMsg.Split('#');
                            if (Mymsg[0] == "000200030006")
                            {
                                MessageBox box = JsonConvert.DeserializeObject<MessageBox>(Mymsg[1]);
                                string sendMsg = "000200030006*" + Mymsg[1];

                                //byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
                                ClientSendMsg(dicSocket.Where(x => x.Key.Contains(box.RID)).FirstOrDefault().Key, sendMsg,0);
                                //dicSocket.Where(x => x.Key.Contains(box.RID)).FirstOrDefault().Value.Send(arrSendMsg);
                                //获得相应的套接字 并将字节数组信息发送出去
                                // dicSocket[lstClients.Text.Trim()].Send(arrSendMsg);


                            }

                            txtMsg.AppendText("SoFlash:" + GetCurrentTime() + "\r\n" + strSRecMsg + "\r\n");
                        }
                        if (buffer[0] == 2)//2为文件名字和长度
                        {
                            string fileNameWithLength = "";
                            try
                            {
                                fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);
                                if (!fileNameWithLength.Contains("Head#"))
                                {
                                    IsHead = false;
                                    sendFile = JsonConvert.DeserializeObject<ScokeSendFile>(fileNameWithLength);

                                    strSRecMsg = sendFile.FileNames.Split('-').First(); //文件名
                                    fileLength = Convert.ToInt64(sendFile.FileNames.Split('-').Last());//文件长度

                                    ScokeSendFile ClientFile= JsonConvert.DeserializeObject<ScokeSendFile>(fileNameWithLength);
                                    ClientFile.FilePath= $@"http://47.115.26.219:8099/{strSRecMsg}";
                                      SendClientMsg = JsonConvert.SerializeObject(ClientFile);
                                    ReceiveUserID = dicSocket.Where(x => x.Key.Contains(sendFile.ReceiveUserID)).FirstOrDefault().Key;
                                  
                                }
                                else
                                {
                                    IsHead = true;
                                    fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);
                                    fileNameWithLength = fileNameWithLength.Replace("Head#", "").Trim();
                                    strSRecMsg = fileNameWithLength.Split('-').First(); //文件名                                    
                                    fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());//文件长度
                                }

                            }
                            catch (Exception ex)
                            {
                                IsHead = true;
                                fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);
                                strSRecMsg = fileNameWithLength.Split('-').First(); //文件名
                                fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());//文件长度
                            }

                      

                        }
    ///文件传输保存在IIS站点下
                        if (buffer[0] == 1)//1为文件
                        {
                            bool IsOk = false;
                            string savePath = "";
                            if (IsHead)
                            {
                                savePath = $@"C:\Files\UserHead\{strSRecMsg}";
                                IsOk = true;
                                //
                            }
                            else
                            {
                                //string fileNameSuffix = strSRecMsg.Substring(strSRecMsg.LastIndexOf('.')); //文件后缀
                                //SaveFileDialog sfDialog = new SaveFileDialog()
                                //{
                                //    Filter = "(*" + fileNameSuffix + ")|*" + fileNameSuffix + "", //文件类型
                                //    FileName = strSRecMsg
                                //};
                                //IsOk = sfDialog.ShowDialog(this) == DialogResult.OK;

                                savePath = $@"C:\文件\SocketUserInfo\{strSRecMsg}";
                                IsOk = true;
                               // savePath = sfDialog.FileName; //获取文件的全路径
                            }
                           

                            //如果点击了对话框中的保存文件按钮 
                            if (IsOk)
                            {                             
                                                                     //保存文件
                                int received = 0;
                                long receivedTotalFilelength = 0;
                                bool firstWrite = true;
                                using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                                {
                                    while (receivedTotalFilelength < fileLength) //之后收到的文件字节数组
                                    {
                                        if (firstWrite)
                                        {
                                            fs.Write(buffer, 1, firstReceived - 1); //第一次收到的文件字节数组 需要移除标识符1 后写入文件
                                            fs.Flush();

                                            receivedTotalFilelength += firstReceived - 1;

                                            firstWrite = false;
                                            continue;
                                        }
                                        received = socketServer.Receive(buffer); //之后每次收到的文件字节数组 可以直接写入文件
                                        fs.Write(buffer, 0, received);
                                        fs.Flush();

                                        receivedTotalFilelength += received;
                                    }
                                    fs.Close();
                                    IsHead = false;
                                }

                                string fName = savePath.Substring(savePath.LastIndexOf("\\") + 1); //文件名 不带路径
                                string fPath = savePath.Substring(0, savePath.LastIndexOf("\\")); //文件路径 不带文件名
                                txtMsg.AppendText(GetCurrentTime() + "\r\n您成功接收了文件" + fName + "\r\n保存路径为:" + fPath + "\r\n");
                                ClientSendMsg(ReceiveUserID, SendClientMsg, 2);
                            }
                        }
                        ///获取在线用户信息
                        if (buffer[0] == 5)
                        {
                            string UserMsg = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);//真实有用的文本信息要比接收到的少1(标识符)
                            if (UserMsg == "001001001")
                            {
                                ServerSendClientOnLine();
                            }
                        }
                        if (buffer[0] == 4)
                        {
                            string UserMsg = Encoding.UTF8.GetString(buffer, 1, firstReceived - 1);//真实有用的文本信息要比接收到的少1(标识符)
                            var strMymsg = UserMsg.Split('#');
                            if (strMymsg[0] == "002002002")
                            {
                                MessageAmanager amanager = JsonConvert.DeserializeObject<MessageAmanager>(strMymsg[1]);
                                //MessageAmanager
                                //获取访问客户端的IP
                                clientIP = (socketServer.RemoteEndPoint as IPEndPoint).Address;
                                //获取访问客户端的Port
                                clientPort = (socketServer.RemoteEndPoint as IPEndPoint).Port;
                                //创建访问客户端的唯一标识 由IP和端口号组成 
                                clientName = "IP: " + clientIP + " Port: " + clientPort;
                                lstClients.Items.Remove(clientName);
                                lstClients.Items.Add(amanager.Message); //在客户端列表添加该访问客户端的唯一标识
                                                                        //var dicSocketS= dicSocket.Where(x => x.Key == clientName).FirstOrDefault();
                                /// dicSocket.Add(clientName, socConnection); //将客户端名字和套接字添加到添加到数据字典中
                                dicSocket = dicSocket.ToDictionary(k => k.Key == clientName ? amanager.Message : k.Key, k => k.Value);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    //dicSocket.Remove(dicSocket.Where(x => x.Value == socketServer).FirstOrDefault().Key);
                    txtMsg.AppendText("系统异常消息:" + ex.Message);
                    break;
                }
            }
        }



        //将信息发送到到客户端
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            ServerSendMsg(txtSendMsg.Text);
        }

        //快捷键 Enter 发送信息
        private void txtSendMsg_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                ServerSendMsg(txtSendMsg.Text);
            }
        }

        /// <summary>
        /// 获取当前系统时间
        /// </summary>
        public DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }

        //关闭服务端
        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //取消客户端列表选中状态
        private void btnClearSelectedState_Click(object sender, EventArgs e)
        {
            lstClients.SelectedItem = null;
        }

        /// <summary>
        /// 发送信息到客户端的方法
        /// </summary>
        /// <param name="sendMsg">发送的字符串信息</param>
        private void ServerSendClientOnLine()
        {
            //  ClearSockectClient();
            string Msg = "";
            foreach (var item in dicSocket)
            {
                if (string.IsNullOrEmpty(Msg))
                {
                    Msg += item.Key;
                }
                else
                {
                    Msg += "#" + item.Key;
                }
            }
            Msg = "0000100020003*" + Msg;

            //将输入的字符串转换成 机器可以识别的字节数组
            byte[] arrSendMsg = Encoding.UTF8.GetBytes(Msg);

            //遍历所有的客户端
            for (int i = 0; i < lstClients.Items.Count; i++)
            {
                try
                {
                    ClientSendMsg(lstClients.Items[i].ToString(), Msg, 0);
                    //dicSocket[lstClients.Items[i].ToString()].Send(arrSendMsg);
                }
                catch (Exception ex)
                {

                }

            }
            //txtMsg.AppendText("您在 " + GetCurrentTime() + " 群发了信息:\r\n" + sendMsg + " \r\n");

        }

        //public void ClearSockectClient()
        //{
        //    string[] keyArr = dicSocket.Keys.ToArray<string>();
        //    for (int i = dicSocket.Count-1; i >=1; i--)
        //    {
        //        try
        //        {

        //            dicSocket[keyArr[i]].Send(Encoding.UTF8.GetBytes("001003"));
        //        }
        //        catch (Exception ex)
        //        {
        //            dicSocket.Remove(keyArr[i]);
        //        }
        //    }




        //}
        /// <summary>
        /// 发送字符串信息到指定客户端的方法
        /// </summary>
        private void ClientSendMsg(string Key, string sendMsg, byte symbol)
        {
            byte[] arrClientMsg = Encoding.UTF8.GetBytes(sendMsg);
            //实际发送的字节数组比实际输入的长度多1 用于存取标识符
            byte[] arrClientSendMsg = new byte[arrClientMsg.Length + 1];
            arrClientSendMsg[0] = symbol;  //在索引为0的位置上添加一个标识符
            Buffer.BlockCopy(arrClientMsg, 0, arrClientSendMsg, 1, arrClientMsg.Length);
            dicSocket[Key].Send(arrClientSendMsg);
         
            // txtMsg.AppendText("SoFlash:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");
        }
        ///计时器 定时清理无效连接
        private void timer1_Tick(object sender, EventArgs e)
        {
            foreach (var item in dicSocket.ToArray())
            {
                try
                {
                    item.Value.Send(Encoding.UTF8.GetBytes("001003"));
                }
                catch (Exception ex)
                {
                    lstClients.Items.Remove(item.Key);
                    dicSocket.Remove(item.Key);
                }


                //if (item.Value.Connected.)
                //{

                //}
            }
            if (dicSocket.Count == 0)
            {
                lstClients.Items.Clear();
            }
        }
    }

    /// <summary>
    ///消息管理
    /// </summary>
    public class MessageAmanager
    {
        /// <summary>
        /// 发送者ID
        /// </summary>
        public string SendUserID { get; set; }
        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// 接收者ID
        /// </summary>
        public string ReceiveUserID { get; set; }

    }
   ///消息管理
    public class MessageBox
    {
        /// <summary>
        /// 接收人
        /// </summary>
        public string RID { get; set; }

        public string Message { get; set; }

        public string Name { get; set; }
        /// <summary>
        /// 发送人
        /// </summary>
        public string SendID { get; set; }
    }

    /// <summary>
    /// 文件发送管理
    /// </summary>
    public class ScokeSendFile
    {
        /// <summary>
        /// 文件名称
        /// </summary>
        public string FileName { get; set; }

        /// <summary>
        /// 解析文件名称
        /// </summary>
        public string FileNames { get; set; }
        /// <summary>
        /// 文件数据
        /// </summary>
        public string FilePath { get; set; }

        /// <summary>
        /// 发送者ID
        /// </summary>
        public string SendUserID { get; set; }
        /// <summary>
        /// 接收者ID
        /// </summary>
        public string ReceiveUserID { get; set; }

        /// <summary>
        /// 0 图片 2 文件
        /// </summary>
        public int Type { get; set; } = 0;
    }
}

下面是客户端发送文件实现: 注意发送文件需要事先动态请求文件读写权限 否则打开文件将会报错

     public async Task<string> OnBrowse()
        {
            try
            {
                var pickFile = await CrossFilePicker.Current.PickFile();
                if (pickFile is null)
                {
                    return "";
                    // 用户拒绝选择文件
                }
                else
                {
                    ScokeSendFile scokeFile = new ScokeSendFile();
                    scokeFile.FileName = pickFile.FileName;
                    scokeFile.FilePath = pickFile.FilePath;
                    scokeFile.ReceiveUserID = Id;
                    scokeFile.SendUserID = DeviceHelp.MyUserID;
                    scokeFile.Type = 2;
                    AddMyFile(scokeFile);
                    DeviceHelp.xamarinSockectClient.SenFile(scokeFile);

                    return pickFile.FilePath;
                    // FileText.Text = $@"选取文件路径 :{pickFile.FilePath}";
                }


            }
            catch (Exception e)
            {
                return e.Message;
                //await DisplayAlert("Alert", "Something went wrong", "OK");
                //if (SettingsPage.loggingEnabled)
                //{
                //    LogUtilPage.Log(e.Message);
                //}
            }



        }




       ///Socke内文件发送处理
            if (string.IsNullOrEmpty(scokeSendFile.FilePath))
            {              
                return;
            }
            fileName = scokeSendFile.FileName;
            //发送文件之前 将文件名字和长度发送过去
            long fileLength = new FileInfo(scokeSendFile.FilePath).Length;
            string totalMsg = string.Format("{0}-{1}", fileName, fileLength);
            scokeSendFile.FileNames = totalMsg;
            string path = JsonConvert.SerializeObject(scokeSendFile);

            ClientSendMsg(path, 2);


            //发送文件
            byte[] buffer = new byte[SendBufferSize];

            using (FileStream fs = new FileStream(scokeSendFile.FilePath, FileMode.Open, FileAccess.Read))
            {
                int readLength = 0;
                bool firstRead = true;
                long sentFileLength = 0;
                while ((readLength = fs.Read(buffer, 0, buffer.Length)) > 0 && sentFileLength < fileLength)
                {
                    sentFileLength += readLength;
                    //在第一次发送的字节流上加个前缀1
                    if (firstRead)
                    {
                        byte[] firstBuffer = new byte[readLength + 1];
                        firstBuffer[0] = 1; //告诉机器该发送的字节数组为文件
                        Buffer.BlockCopy(buffer, 0, firstBuffer, 1, readLength);

                        socketClient.Send(firstBuffer, 0, readLength + 1, SocketFlags.None);

                        firstRead = false;
                        continue;
                    }
                    //之后发送的均为直接读取的字节流
                    socketClient.Send(buffer, 0, readLength, SocketFlags.None);
                }
                fs.Close();
            }

下面是android端接受文件处理

/// <summary>
       /// 好友发来的文件
       /// </summary>
       /// <param name="scokeSendFile"></param>
       public void AddFriendFile(ScokeSendFile scokeSendFile)
       {
           Device.BeginInvokeOnMainThread(() =>
           {

               light monkey = new light();
               monkey.Text = scokeSendFile.FileName;
               monkey.TextIsVisibles = false;
               monkey.ImageIsVisibles = true;
               var fileKZName = Path.GetExtension(scokeSendFile.FilePath).ToLower();
               if (scokeSendFile.Type == 2 && !_fileNameKZ.Contains(fileKZName.ToLower()))
               {
                   monkey.ImageUrl = "wj.png";
                   monkey.FilePath = "wj.png";
               }
               else
               {
                    monkey.ImageUrl = scokeSendFile.FilePath;
                   //monkey.ImageUrl = "wj.png";
                   monkey.FilePath = scokeSendFile.FilePath;
               }
               //  monkey.ImageUrl = ""; //"https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"// "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
               monkey.FriendImageIsVisibles = true;

               monkey.FriendImageUrl = "https://profile.csdnimg.cn/8/5/A/1_psu521";
               monkey.MyImageIsVisibles = false;
               //   monkey.Click += new EventHandler(Click);
               monkey.TextHorizontalOptions = LayoutOptions.Start;
               //monkey.Grd_Heigt = 200;
               //monkey.Grd_Heigt = monkey.Text.Length >= 20 ? (monkey.Text.Length / 20) * 24 : 40;  //GridLength.Auto;
               //monkey.TextWidth = monkey.Text.Length > 17 ? App.ScreenWidth - 110 : (App.ScreenWidth - 110) * (monkey.Text.Length * 0.018);
               monkey.Grd_Heigt = (monkey.Text.Length >= 10 ? (monkey.Text.Length / 7) * 24 : 40) + 30;  //GridLength.Auto;
               monkey.TextWidth = monkey.Text.Length > (App.ScreenWidth - 110) / 24 ? App.ScreenWidth - 110 : (App.ScreenWidth - 50) * (monkey.Text.Length * 0.08);
               monkey.MsgTime = DateTime.Now.ToString();
               // HomeViewModel.AddFiyee(monkey);
               lights.Add(monkey);
               X_listView_ScrollTo();

               //SampleMessage sample = new SampleMessage { Text = box.Message, Id = box.SendID };
               //sample.User = new SampleUser() { Id = box.SendID, Avatar = box.Name, Name = box.Name };

               //messagesListAdapter.AddToStart(sample, true);
           });
       }

下面是查看文件处理 通过httpClient 下载文件

  private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
        {
            try
            {
                //ImageViewPage
                if (sender is MyImage)
                {
                    MyImage myImage = sender as MyImage;

                    var data = lights.Where(x => x.ID == myImage.Text).FirstOrDefault();
                    var fileKZName = Path.GetExtension(data.FilePath).ToLower();
                    ///如果是图片类型 则打开一个image页面 显示 否则就跳转到浏览器打开
                    if (myImage.imageType == ImageType.body && _fileNameKZ.Contains(fileKZName.ToLower()))
                    {
                        if (data.FriendImageIsVisibles)
                        {
                            var httpData =  HttlClientDow(data.FilePath);           
                             
                            Navigation.PushAsync(new ImageViewPage(ImageSource.FromStream(() => httpData)), true);
                        }
                        else
                        {
                            Navigation.PushAsync(new ImageViewPage(myImage.Source), true);
                        }
                    }
                    else
                    {
                    ///浏览器打开文件
                        await Browser.OpenAsync(data.FilePath, new BrowserLaunchOptions
                        {
                            LaunchMode = BrowserLaunchMode.SystemPreferred,
                            TitleMode = BrowserTitleMode.Show,
                            PreferredToolbarColor = Color.AliceBlue,
                            PreferredControlColor = Color.Violet
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                DevHelp.DeviceHelp.Toast.ShortAlert(ex.Message);
            }
        }
 

下面是效果图:程序内打开
在这里插入图片描述
在这里插入图片描述

跳转浏览器打开在这里插入图片描述
自此完结 谢谢大家
需要源码请联系博主微信:
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/30354.html

客户端  文件  发送  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1