123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- using LJLib.Net.SPI.Client;
- using LJLib.Tools.Helper;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.IO.Compression;
- using System.Text;
- using System.Threading;
- namespace LJLib.Client
- {
- public sealed class P1Client : ILJClient
- {
- private const byte NEW_ALLGZIP = 0x10;
- private const byte SVRBEAT = 0x08;
- private const byte PROTOCOL_FLAG = 0x04;
- private const byte READ_GZIP = 0x02;
- private const byte WRITE_GZIP = 0x01;
- private Stream _stream = null;
- private object syncRoot = new object();
- public P1Client(Stream stream)
- {
- _stream = stream;
- }
- public string DoExcute(string apiName, string requestJSON)
- {
- lock (syncRoot)
- {
- var apiname = apiName;
- var firstByte = new[]
- {
- (byte)(SVRBEAT | PROTOCOL_FLAG | READ_GZIP | WRITE_GZIP | NEW_ALLGZIP),
- (byte)(SVRBEAT | PROTOCOL_FLAG | READ_GZIP | WRITE_GZIP),
- (byte)(SVRBEAT | PROTOCOL_FLAG),
- };
- var headByte = firstByte[0];
- if (headByte > 0x1F || (headByte & PROTOCOL_FLAG) != PROTOCOL_FLAG)
- {
- throw new Exception("不支持协议" + headByte.ToString("X2"));
- }
- if ((headByte & NEW_ALLGZIP) == NEW_ALLGZIP)
- {
- if ((headByte & READ_GZIP) != READ_GZIP)
- {
- throw new Exception("协议异常:新协议必须压缩发送");
- }
- if ((headByte & WRITE_GZIP) != WRITE_GZIP)
- {
- throw new Exception("协议异常:新协议必须压缩返回");
- }
- }
- if (!_stream.CanWrite)
- {
- throw new Exception(string.Format("远端服务已中断(不能写)"));
- }
- _stream.Write(firstByte, 0, 1);
- var ostream = _stream;
- if ((headByte & READ_GZIP) == READ_GZIP)
- {
- ostream = new MemoryStream();
- }
- string str = apiname + requestJSON;
- WriteStringAndFiles(ostream, str, null, null);
- if ((headByte & READ_GZIP) == READ_GZIP)
- {
- using (ostream)
- using (var gzipms = new MemoryStream())
- using (var gzip = new GZipStream(gzipms, CompressionMode.Compress, true))
- {
- ostream.Seek(0, SeekOrigin.Begin);
- StreamHelper.StreamCopy(gzip, ostream);
- gzip.Close();
- if ((headByte & NEW_ALLGZIP) == NEW_ALLGZIP)
- {
- var filelen = BitConverter.GetBytes((int)gzipms.Length);
- _stream.Write(filelen, 0, filelen.Length);
- }
- gzipms.Seek(0, SeekOrigin.Begin);
- StreamHelper.StreamCopy(_stream, gzipms);
- }
- }
- if (!_stream.CanRead)
- {
- throw new Exception(string.Format("远端服务已中断(不能读)"));
- }
- if ((headByte & SVRBEAT) == SVRBEAT)
- {
- var oldTimeout = _stream.ReadTimeout;
- _stream.ReadTimeout = 10000;
- var hasRslt = _stream.ReadByte();
- while (hasRslt == 0)
- {
- Thread.Sleep(100);
- if (!_stream.CanRead)
- {
- throw new Exception(string.Format("远端服务已中断(不能读)"));
- }
- hasRslt = _stream.ReadByte();
- if (hasRslt == -1)
- {
- throw new Exception(string.Format("远端服务已中断(不能读)"));
- }
- }
- _stream.ReadTimeout = oldTimeout;
- }
- Debug.Write("WaitServer End");
- var istream = _stream;
- MemoryStream ms = null;
- GZipStream gzipstream = null;
- if ((headByte & WRITE_GZIP) == WRITE_GZIP)
- {
- if ((headByte & NEW_ALLGZIP) == NEW_ALLGZIP)
- {
- ms = new MemoryStream();
- var allen = new byte[4];
- _stream.Read(allen, 0, allen.Length);
- var alen = BitConverter.ToInt32(allen, 0);
- StreamHelper.StreamCopy(ms, _stream, alen);
- Debug.Write("ReadResponseFromNet End");
- ms.Seek(0, SeekOrigin.Begin);
- gzipstream = new GZipStream(ms, CompressionMode.Decompress, false);
- istream = gzipstream;
- }
- else
- {
- gzipstream = new GZipStream(_stream, CompressionMode.Decompress, true);
- istream = gzipstream;
- }
- }
- byte[] bytes;
- Dictionary<string, byte[]> rfiles = new Dictionary<string, byte[]>();
- using (ms)
- using (gzipstream)
- {
- var reader = new BinaryReader(istream);
- var len = reader.ReadInt32();
- bytes = reader.ReadBytes(len);
- var filecnt = reader.ReadByte();
- for (int i = 0; i < filecnt; i++)
- {
- var namelen = reader.ReadInt32();
- var namebytes = reader.ReadBytes(namelen);
- var datalen = reader.ReadInt32();
- var databytes = reader.ReadBytes(datalen);
- rfiles.Add(Encoding.UTF8.GetString(namebytes), databytes);
- }
- Debug.Write("ReadResponse End");
- }
- var strrsp = Encoding.UTF8.GetString(bytes);
- return strrsp;
- }
- }
- private static void WriteStringAndFiles(Stream ostream, string str, IDictionary<string, string> files, Dictionary<string, byte[]> exfiles)
- {
- var strbytes = Encoding.UTF8.GetBytes(str);
- var lenbytes = BitConverter.GetBytes(strbytes.Length);
- ostream.Write(lenbytes, 0, lenbytes.Length);
- ostream.Write(strbytes, 0, strbytes.Length);
- ostream.Flush();
- if (files == null)
- {
- files = new Dictionary<string, string>();
- }
- if (exfiles == null)
- {
- exfiles = new Dictionary<string, byte[]>();
- }
- var shortbytes = BitConverter.GetBytes((short)(files.Count + exfiles.Count));
- ostream.Write(shortbytes, 0, shortbytes.Length);
- foreach (var file in files)
- {
- var namebytes = Encoding.UTF8.GetBytes(file.Key);
- var namelen = BitConverter.GetBytes(namebytes.Length);
- ostream.Write(namelen, 0, namelen.Length);
- ostream.Write(namebytes, 0, namebytes.Length);
- ostream.Flush();
- using (var fs = File.OpenRead(file.Value))
- {
- var filelen = BitConverter.GetBytes((int)fs.Length);
- ostream.Write(filelen, 0, filelen.Length);
- byte[] buff = new byte[10240];
- int read = 0;
- while ((read = fs.Read(buff, 0, buff.Length)) > 0)
- {
- ostream.Write(buff, 0, read);
- ostream.Flush();
- }
- }
- }
- foreach (var file in exfiles)
- {
- var namebytes = Encoding.UTF8.GetBytes(file.Key);
- var namelen = BitConverter.GetBytes(namebytes.Length);
- ostream.Write(namelen, 0, namelen.Length);
- ostream.Write(namebytes, 0, namebytes.Length);
- ostream.Flush();
- var filelen = BitConverter.GetBytes((int)file.Value.Length);
- ostream.Write(filelen, 0, filelen.Length);
- using (var ms = new MemoryStream(file.Value))
- {
- byte[] buff = new byte[10240];
- int read = 0;
- while ((read = ms.Read(buff, 0, buff.Length)) > 0)
- {
- ostream.Write(buff, 0, read);
- ostream.Flush();
- }
- }
- ostream.Flush();
- }
- ostream.Flush();
- }
- public void Beat()
- {
- lock (syncRoot)
- {
- _stream.WriteByte(0x00);
- }
- }
- public void Dispose()
- {
- _stream.Dispose();
- }
- }
- }
|