0

I have a fully working VPS media server in C++ and Java that allows devices (both intel and android) to play a video playlist and be updated on the fly.

I've also got a device manager written in Java and using the standard UI. This is the problem, it doesn't work on mobile devices.

So, I've started working on a NodeJS server, using 'socket.io' and 'net'. Which so far is all working fine. The Node server connects with the Java server, the Java server converts its library to a JSON string and the Node server gets (apparently) the correct data. At least that's what is shown on the console log.

The problem I am having is when the client browser receives this data, I'm stuck.

The server setup is:

  1. Java - Device server (on its own port)

  2. Java - Device manager (own port)

  3. C++ - Faster transferring of encrypted data

  4. And now a Node server which communicates (seemingly perfectly) with '2.'.

I'll try to make the code snippets pretty.

This creates the JSON that gets sent to the Node server (seemingly) working great at the mo. It creates the JSON string and sends it over the TCP localhost connection great.

private void get_videos(BufferedReader br, BufferedWriter bw)
        throws IOException {
    //bw.write("[{name:'Carl'}]");
    //bw.flush();
    JSONArray media = new JSONArray();
    
    synchronized (dev_server2.deviceServer_Main.library.media_lock) {
        
        JSONArray areaArray = new JSONArray();
        
        for (Area area : dev_server2.deviceServer_Main.library.media) {
            
            //JSONObject newArea = new JSONObject();
            //newArea.put("area", area.name);
            
            //areaArray.put(newArea);
            areaArray.put(area.name);
            
            JSONArray catArray = new JSONArray();
            
            for (Category cat : area.category) {
                
                catArray.put(cat.name);
                JSONArray vidArray = new JSONArray();
                
                for (VideoFile vid : cat.videos) {
                    
                    JSONObject vidObject = new JSONObject();
                    
                    vidObject.put("name", vid.name);
                    vidObject.put("description", vid.description);
                    vidObject.put("watershed", vid.watershed);
                    
                    vidArray.put(vidObject);
                }
                
                catArray.put(vidArray);
            }
            
            areaArray.put(catArray);
        }
        media.put(areaArray);
        bw.write(areaArray.toString());
    }
    
    //bw.write(areaArray.toString());
    bw.flush();
}

On the Node side which receives the data and logs it correctly:

const global = require("../global/global.js");
const node_port = 2000;

function dm_get_videos(socket) {
    videos = [];
    
    client = new global.net.Socket();
    client.connect({port: node_port, host: 'localhost'},
    function() {
        console.log("dm_get_videos");
        client.write("get_videos\n");
    });
    
    client.on("data", function(data) {
        console.log("TCP socket data: " + data);
        socket.emit("get_videos", data);
        //socket.emit("get_videos", JSON.stringify(data));
    });
    
    client.on("end", function() {
        console.log("TCP socket disconnected");
    });
    
    client.on("error", function() {
        console.log("ERROR: getting videos");
    });
}

module.exports = {
    get_videos : dm_get_videos
};

Which gives the output in the console log: (I'll tidy this up in an edit)

dm_get_videos
TCP socket data: ["Home",["Home",[{"watershed":false,"name":"Runcorn-TheUnion-FridayNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-LADIESdartsNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-MondayDominoesNEW.MP4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-Pool.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-SaturdayKaraokeNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-SkySportsNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-SundayBingoNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-TuesdayUnionNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-WednesdayQuizNEW.mp4","description":""},{"watershed":false,"name":"Runcorn-TheUnion-WelcomeUnion.mp4","description":""}]]]
TCP socket disconnected

On the client side (browser), is were I am stuck.

socket get_videos: [object ArrayBuffer]
landing.js:145 data: 20
VM1960:1 Uncaught SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)
    at r.<anonymous> (landing.js:146)
    at r.emit (index.js:83)
    at r.onevent (index.js:83)
    at r.onpacket (index.js:83)
    at r.<anonymous> (index.js:83)
    at r.emit (index.js:83)
    at r.ondecoded (index.js:83)
    at a.<anonymous> (index.js:83)
    at a.r.emit (index.js:83)

Using the code (browser side): (I'm aware of the SyntaxError because of researching)

// get video list
socket.emit("get_videos");

socket.on("get_videos", (res) => {
    data = "";
    data += res;
    //pdata = JSON.parse(data);
    console.log("socket get_videos: " + data);
    console.log("data: " + data.length);
    console.log(JSON.parse(data));
});

If anyone can help in directing me into working with this data on the client side then great. I've also tried sending it as raw data and converting it back. I'm used to working with C++ and Java. I have used Javascript a lot and used JSON, but I don't know how to now, access this array.

Thanks in advance.

EDIT 1: Output of the JSON data

[
    "Home",
    [
        "Home",
        [
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-FridayNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-LADIESdartsNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-MondayDominoesNEW.MP4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-Pool.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-SaturdayKaraokeNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-SkySportsNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-SundayBingoNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-TuesdayUnionNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-WednesdayQuizNEW.mp4",
                "description": ""
            },
            {
                "watershed": false,
                "name": "Runcorn-TheUnion-WelcomeUnion.mp4",
                "description": ""
            }
        ]
    ]
]

Output of console.log(res); shows:

[object ArrayBuffer]

EDIT 2: With help from Tomalak (cheers buddy)

I've now got the string data using

console.log(new TextDecoder().decode(res));

How do I iterate through the above data? I'm only used to basic JSON data and not multi nested arrays in JSON. Java and C++ fine, but this???

WLGfx
  • 1,169
  • 15
  • 31
  • 1
    `Unexpected token o` - this usually happens when an object has been used as a string, so the output is `[object Object]` which isn't valid JSON – Jaromanda X Oct 13 '20 at 08:35
  • note ... `data = ""; data += res;` is just `data = "" + res;` which may well be the problem – Jaromanda X Oct 13 '20 at 08:36
  • `socket.emit("get_videos", JSON.stringify(data));` - your data *already is* JSON. Putting it though `JSON.stringify()` again is an error. – Tomalak Oct 13 '20 at 08:40
  • At the moment, at least I'm getting an object. The unexpected token error I'm aware of. I need to actually now parse the data itself with which I'm struggling to do. I'll try and tidy up the JSON string which I think will help with my question. (Just trying to find a decent editor to do so) – WLGfx Oct 13 '20 at 08:41
  • @Tomalak That's why it's commented out. I've been trying all kinds. It's the client side now I'm struggling with. – WLGfx Oct 13 '20 at 08:44
  • Use `console.log(res)` in your client. What does it show? – Tomalak Oct 13 '20 at 08:46
  • Updated with a prettified JSON output and the 'res' output. I'm not fully versed with Javascript and JSON objects, so I'm hoping someone can help me parse this data. – WLGfx Oct 13 '20 at 08:54
  • You're getting an `ArrayBuffer`. This needs to be converted to string explicitly. Try https://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers – Tomalak Oct 13 '20 at 09:01
  • 1
    @Tomalak Using `console.log(new TextDecoder().decode(res));` has done the trick so far. Now on to parsing the data. Darn it... Source: https://stackoverflow.com/a/41180394/2979092 – WLGfx Oct 13 '20 at 09:23
  • Maybe it's time to streamline the question a bit, if there still is a question left after this. – Tomalak Oct 13 '20 at 09:45
  • Yeah, I'm thinking on this. And it's mostly about iterating through the 3 arrays in the JSON data. I'll add that bit shortly. Cheers buddy. Your link pointed me in a direction that helped me look further. I'm not a Javascript coder, mainly C++ and Java. – WLGfx Oct 13 '20 at 09:56
  • On an unrelated note, I would probably not go with nested arrays (`["Home", ["Home", [{...}]]]`), but with nested objects (`{"Home": {"Home": [{...}]}}`). This makes consuming the data in JS easier: `data.Home.Home.forEach(item => ...)` – Tomalak Oct 13 '20 at 11:22
  • The `["Home", ["Home"], [{}]]]` From the Java function posted adds each of these as arrays, which I do actually need. These are `Area`, `Category` and `Videos`, so there `Home` is just my testing rig. There will be a lot more in the `Area` array as well as the others. – WLGfx Oct 13 '20 at 13:45

0 Answers0