Send Scaned Image, Web Socket

0

My problem is when using the ws Web Socket protocol that sends a giant string (a size chain of about 7 to 8 digits ex: 78872125 ) which is an image that I scan and the I turn it into base 64 and then I'll commit it to bytes in order to send it through the protocol.

This is the code section in c# where client.Send(Bytes, Bytes.Length, SocketFlags.None); is the part where you sent the message to a web socket in HTML5 .

private static void OnAccept(IAsyncResult result)
    {
        byte[] buffer = new byte[1024];
        try
        {
            Socket client = null;
            string headerResponse = "";
            if (serverSocket != null && serverSocket.IsBound)
            {
                client = serverSocket.EndAccept(result);
                var i = client.Receive(buffer);
                headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i);
                Console.WriteLine(headerResponse);

            }
            if (client != null)
            {
                var key = headerResponse.Replace("ey:", "'")
                          .Split(''')[1]                     
                          .Replace("\r", "").Split('\n')[0]  
                          .Trim();

                var test1 = AcceptKey(ref key);

                var newLine = "\r\n";

                var response = "HTTP/1.1 101 Switching Protocols" + newLine
                     + "Upgrade: websocket" + newLine
                     + "Connection: Upgrade" + newLine
                     + "Sec-WebSocket-Accept: " + test1 + newLine + newLine;
                client.Send(System.Text.Encoding.UTF8.GetBytes(response));

                var i = client.Receive(buffer);
                //Console.WriteLine("Iniciando escanneo");
                string msasd = "";
                try
                {
                    List<string> devices = WIAScanner.GetDevices();
                    ICommonDialog instance = (ICommonDialog)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("850D1D11-70F3-4BE5-9A11-77AA6B2BB201")));

                    Device device = instance.ShowSelectDevice(WiaDeviceType.UnspecifiedDeviceType, true, false);
                    if (device != null)
                    {
                        List<Image> images = WIAScanner.Scan(device.DeviceID);
                        foreach (Image image in images)
                        {
                            Bitmap objBitmap = new Bitmap(image, new Size(1250, 1550));
                            MemoryStream ms = new MemoryStream();
                            objBitmap.Save(ms, ImageFormat.Jpeg);
                            msasd = Convert.ToBase64String(ms.ToArray());
                        }
                    }
                }
                catch (Exception exc)
                {
                    //
                }
                //Console.WriteLine("Escaneo Terminado...");
                //Console.WriteLine("Iniciando Envio de paquete");
                byte[] Bytes = CodificarMensajeParaEnviar(msasd);
                client.Send(Bytes, Bytes.Length, SocketFlags.None);

                //Console.WriteLine("Envio Terminado");
                //Console.WriteLine("Se enviaron {0} bytes de informacion", msasd.Length);
            }
        }
        catch (SocketException exception)
        {
            throw exception;
        }
        finally
        {
            if (serverSocket != null && serverSocket.IsBound)
            {
                serverSocket.BeginAccept(null, 0, OnAccept, null);
            }
        }
    }

Good Now the script of my html where I get the message that is the scanned image in base64 that sent C # , where

ws.onmessage = function (evt) {
                cadena=evt.data;//aqui deberia de llegar mi mensaje
                cFunction(cadena);
            };

evt.data is the string that contains the result and well after that I send it to be stored by ajax to a route Laravel where there is no problem, the script complete is:.

<script type="text/javascript">
    function scannear(){
        loadDoc("ws://127.0.0.1:9000", myFunction);
    }
    function loadDoc(url, cFunction) {
        var cadena="";
        if ("WebSocket" in window) {
            var ws = new WebSocket(url);
            ws.onopen = function () {
                alert("Esta a punto de escanear documentos, asegurese de que la impresora este encendida");
                ws.send("scannear");
            };
            ws.onerror = function (error) {
                console.log('WebSocket Error');
            };
            ws.onmessage = function (evt) {
                cadena=evt.data;//aqui deberia de llegar mi mensaje
                cFunction(cadena);
            };
            ws.onclose = function () {
                $("#mymodal").modal();
            };
        }else{
            $("#mymodalchrome").modal();
        }
    };
    function myFunction(cadena) {
        $.ajax({
            url:'{{url('submitimagen')}}',
            type:'post',
            data:{imagen:cadena,_token:'{{csrf_token()}}',type:"documento"},
            success:function(data){
                if(data.ok){
                    setTimeout('location.reload()',1000);
                }else{
                    alert("error");
                }
            },
            error:function(error){
                console.log("error:"+error);
                alert(error);
            }
        });
    }
</script>

Well I hope you have understood with that bit of code since publishing everything would be very long and boring to read it for you.

  

Then the problem is only sending / receiving this giant data
Since with short chains like "hola mundo" everything works correctly

    
asked by Shassain 16.08.2017 в 21:11
source

2 answers

0

Greetings, solve the problem with all the advice you gave me, for which I now publish the solution:

Replace the following code

//Console.WriteLine("Escaneo Terminado...");
//Console.WriteLine("Iniciando Envio de paquete");
byte[] Bytes = CodificarMensajeParaEnviar(msasd);
client.Send(Bytes, Bytes.Length, SocketFlags.None);
//Console.WriteLine("Envio Terminado");
//Console.WriteLine("Se enviaron {0} bytes de informacion", msasd.Length);

For a partition algorithm of Bytes and send it by sections (as advised), the code is as follows:

//Console.WriteLine("Escaneo Terminado...");
//Console.WriteLine("Escaneo Terminado...");
//Console.WriteLine("Iniciando Envio de paquete");
int particion = msasd.Length / 100;
int mod = msasd.Length % 100;
for (int l = 0; l < 100; l++)
{
    byte[] Bytes = CodificarMensajeParaEnviar(msasd.Substring(particion*l,particion));
    int k = client.Send(Bytes, Bytes.Length, SocketFlags.None);                    
}
if (mod != 0)
{
    byte[] Bytes2 = CodificarMensajeParaEnviar(msasd.Substring(particion * 100));
    int k2 = client.Send(Bytes2, Bytes2.Length, SocketFlags.None);
}
else {
    byte[] Bytes2 = CodificarMensajeParaEnviar("");
    int k2 = client.Send(Bytes2, Bytes2.Length, SocketFlags.None);
}
//Console.WriteLine("Envio Terminado");
//Console.WriteLine("Se enviaron {0} bytes de informacion", msasd.Length);

I divided the message into 100 parts, but 101 messages are sent in case there are residues or not (if there is no waste sent an empty string), for which on the client side I receive 101 messages as follows:

var cant=0;
ws.onmessage = function (evt) {
    cadena+=evt.data;
    cant++;
    if(cant==101){
        cFunction(cadena);
    }
};

Concatenate the messages and everything went well, thanks for everyone's help.

    
answered by 19.09.2017 / 06:00
source
2

The implementation of websocket as that of any socket requires that you give enough time to make the plot complete, when you send a small data like a hello world, it works because the data can be extracted just by reading the buffer once , but with an image, for the size that is usually more than 1024 bytes, can not be read complete with a single reading, then there are several strategies to address this problem.

  • The first is that you add the size of the frame to the first 4 bytes so that after you try to read that number of bytes and secure the image (with a while and pausing), now this strategy It would be if it were a pure socket.

  • Another strategy is to split the package or the image in this case so that small packages of the same size are sent, in such a way that it always ensures that I am going to read a quantity of data that I have planned, which combined with the previous strategy, they guarantee the reading of the package

  • For a websocket it already warns us when the message arrives complete or not, using the property WebSocketReceiveResult.EndOfMessage of the own implementation of .net saving the work of having to enter to achieve to establish the frame size, also He usually split the plot and send it in pieces, which implies the obligatory use of the property I mention. in the following links there is an example of how to use websocket and in the comments document the use of the property to which I mention.

link

link

Any doubt I remain attentive

    
answered by 22.08.2017 в 14:55