public void OnReloaded(DisquuunSocket reloadedSocket) { lock (lockObject) { if (stackSocket.IsQueued()) { if (reloadedSocket.IsChoosable()) { reloadedSocket.SetBusy(); var commandAndData = stackSocket.Dequeue(); if (commandAndData.data.Length == 0) { Disquuun.Log("OnReloaded len = 0.", true); } switch (commandAndData.executeType) { case DisquuunExecuteType.ASYNC: { reloadedSocket.Async(commandAndData.command, commandAndData.data, commandAndData.Callback); return; } case DisquuunExecuteType.LOOP: { reloadedSocket.Loop(commandAndData.command, commandAndData.data, commandAndData.Callback); return; } } } } } }
private void OnSend(object unused, SocketAsyncEventArgs args) { try { switch (args.SocketError) { case SocketError.Success: { var token = args.UserToken as SocketToken; switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.SENDED; break; } case SocketState.RECEIVED: { if (token.continuation) { // ready for next loop receive. token.readableDataLength = 0; token.receiveArgs.SetBuffer(token.receiveBuffer, 0, token.receiveBuffer.Length); if (!token.socket.ReceiveAsync(token.receiveArgs)) { OnReceived(token.socket, token.receiveArgs); } token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length); if (!token.socket.SendAsync(token.sendArgs)) { OnSend(token.socket, token.sendArgs); } return; } token.socketState = SocketState.OPENED; SocketReloaded(this); return; } } return; } default: { Disquuun.Log("onsend error, " + args.SocketError, true); // if (Error != null) { // var error = new Exception("send error:" + socketError.ToString()); // Error(error); // } return; } } } catch (Exception e) { Disquuun.Log("OnSend e:" + e, true); } }
public virtual void Async(DisqueCommand command, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback) { lock (stackLockObject) { try { this.stackedDataQueue.Enqueue(new StackCommandData(DisquuunExecuteType.ASYNC, command, data, Callback)); } catch (Exception e) { Disquuun.Log("failed to start async:" + e); } } }
public void Disconnect() { try { socketToken.socketState = SocketState.CLOSING; External.Disconnect(socketToken, null); socketToken.socketState = SocketState.CLOSED; } catch (Exception e) { Disquuun.Log("Disconnect e:" + e.Message, true); } return; }
/* * Core methods of Disquuun. */ /** * method for Sync execution of specific Disque command. * DEPRECATED. only use for testing. */ public override DisquuunResult[] DEPRECATED_Sync(DisqueCommand command, byte[] data) { try { socketToken.socket.Send(data); var currentLength = 0; var scanResult = new DisquuunAPI.ScanResult(false); while (true) { // waiting for head of transferring data or rest of data. socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, 1, SocketFlags.None); currentLength = currentLength + 1; var available = socketToken.socket.Available; var readableLength = currentLength + available; { if (socketToken.receiveBuffer.Length < readableLength) { // Disquuun.Log("サイズオーバーしてる " + socketToken.receiveBuffer.Length + " vs:" + readableLength); Array.Resize(ref socketToken.receiveBuffer, readableLength); } } // read rest. socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, available, SocketFlags.None); currentLength = currentLength + available; scanResult = DisquuunAPI.ScanBuffer(command, socketToken.receiveBuffer, currentLength, socketId); if (scanResult.cursor == currentLength) { break; } // continue reading data from socket. // if need, prepare for next 1 byte. if (socketToken.receiveBuffer.Length == readableLength) { Array.Resize(ref socketToken.receiveBuffer, socketToken.receiveBuffer.Length + 1); } } socketToken.socketState = SocketState.OPENED; return(scanResult.data); }catch (Exception e) { Disquuun.Log("e:" + e, true); throw e; } }
/* * default pooled socket + disposable socket shared */ private void StartReceiveAndSendDataAsync(DisqueCommand command, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback) { try { // ready for receive. socketToken.readableDataLength = 0; socketToken.receiveArgs.SetBuffer(socketToken.receiveBuffer, 0, socketToken.receiveBuffer.Length); if (!socketToken.socket.ReceiveAsync(socketToken.receiveArgs)) { OnReceived(socketToken.socket, socketToken.receiveArgs); } socketToken.currentCommand = command; socketToken.currentSendingBytes = data; socketToken.AsyncCallback = Callback; try { socketToken.sendArgs.SetBuffer(data, 0, data.Length); } catch (Exception e) { Disquuun.Log("StartReceiveAndSendDataAsync before error,", true); Disquuun.Log("sendArgs setBuffer error:" + e.Message); // renew. potential error is exists and should avoid this error. var endPoint = socketToken.sendArgs.RemoteEndPoint; socketToken.sendArgs = new SocketAsyncEventArgs(); socketToken.sendArgs.RemoteEndPoint = endPoint; socketToken.sendArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnSend); } if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } } catch (Exception e1) { Disquuun.Log("StartReceiveAndSendDataAsync error:" + e1.Message, true); } }
private void OnReceived(object unused, SocketAsyncEventArgs args) { var token = (SocketToken)args.UserToken; if (args.SocketError != SocketError.Success) { switch (token.socketState) { case SocketState.CLOSING: case SocketState.CLOSED: { // already closing, ignore. return; } default: { switch (args.SocketError) { case SocketError.ConnectionReset: { Disquuun.Log("ConnectionResetが出てる. " + " token.socketState:" + token.socketState, true); break; } default: { Disquuun.Log("onReceive default token.socketState:" + token.socketState + " error:" + args.SocketError, true); break; } } Disconnect(); var e1 = new Exception("receive status is not good."); SocketClosed(this, "failed to receive.", e1); return; } } } if (args.BytesTransferred == 0) { return; } var bytesAmount = args.BytesTransferred; // update as read completed. token.readableDataLength = token.readableDataLength + bytesAmount; var result = DisquuunAPI.ScanBuffer(token.currentCommand, token.receiveBuffer, token.readableDataLength, socketId); // data is totally read and executable. if (result.cursor == token.readableDataLength) { var continuation = token.AsyncCallback(token.currentCommand, result.data); // update continuation status. token.continuation = continuation; if (continuation) { switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.RECEIVED; break; } case SocketState.SENDED: { // ready for next loop receive. token.readableDataLength = 0; token.receiveArgs.SetBuffer(token.receiveBuffer, 0, token.receiveBuffer.Length); if (!token.socket.ReceiveAsync(token.receiveArgs)) { OnReceived(token.socket, token.receiveArgs); } try { token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length); } catch { var sendArgs = new SocketAsyncEventArgs(); sendArgs.RemoteEndPoint = token.receiveArgs.RemoteEndPoint; sendArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnSend); sendArgs.UserToken = token; token.sendArgs = sendArgs; token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length); } if (!token.socket.SendAsync(token.sendArgs)) { OnSend(token.socket, token.sendArgs); } break; } default: { // closing or other state. should close. break; } } return; } // end of loop or end of async. switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.RECEIVED; break; } case SocketState.SENDED: { token.socketState = SocketState.OPENED; SocketReloaded(this); break; } default: { break; } } return; } // not yet received all data. // continue receiving. /* * note that, * * SetBuffer([buffer], offset, count)'s "count" is, actually not count. * * it's "offset" is "offset of receiving-data-window against buffer", * but the "count" is actually "size limitation of next receivable data size". * * this "size" should be smaller than size of current bufferSize - offset && larger than 0. * * e.g. * if buffer is buffer[10], offset can set 0 ~ 8, and, * count should be 9 ~ 1. * * if vaiolate to this rule, ReceiveAsync never receive data. not good behaviour. * * and, the "buffer" is treated as pointer. this API treats the pointer of buffer directly. * this means, when the byteTransferred is reaching to the size of "buffer", then you resize it to proper size, * * you should re-set the buffer's pointer by using SetBuffer API. * * * actually, SetBuffer's parameters are below. * * socket.SetBuffer([bufferAsPointer], additionalDataOffset, receiveSizeLimit) */ var nextAdditionalBytesLength = token.socket.Available; if (token.readableDataLength == token.receiveBuffer.Length) { Array.Resize(ref token.receiveBuffer, token.receiveArgs.Buffer.Length + nextAdditionalBytesLength); } var receivableCount = token.receiveBuffer.Length - token.readableDataLength; token.receiveArgs.SetBuffer(token.receiveBuffer, token.readableDataLength, receivableCount); if (!token.socket.ReceiveAsync(token.receiveArgs)) { OnReceived(token.socket, token.receiveArgs); } }