webrtc学习笔记9(datachannel在jslinux的应用,java版本)

阅读更多
目标:使用java的websocket作为datachannl建立连接
让jslinux可以实现两个浏览器数据互通。

效果图 webrtc学习笔记9(datachannel在jslinux的应用,java版本)_第1张图片

原理:
jslinux已经实现了/dev/clipboard与浏览器的textarea的联通,
利用datachannel把两个浏览器的textarea交互,实现jslinux之间的数据交互

增加room概念,进入同一个room的两个页面才可以互相通信
要求tomcat7.0.62
java代码,java的websocket使给datachannel建立连接.
package com.hao;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

public class RoomWebSocketServlet extends WebSocketServlet {
	public static Map slist = new HashMap();

	protected StreamInbound createWebSocketInbound(String subProtocol,
			HttpServletRequest request) {
		System.out.println("room:"+request.getParameter("r"));
		String arg="0";
		if(null!=request.getParameter("r")){
			arg=request.getParameter("r");
		}
		return new MyMessageInbound(arg);
	}

	public int getUserCount() {
		return slist.size();
	}

	private class MyMessageInbound extends MessageInbound {
		WsOutbound myoutbound;
		String mykey;
		String room;
		public MyMessageInbound(String room){
			this.room=room;
		}
		@Override
		public void onOpen(WsOutbound outbound) {
			try {
				System.out.println("websocket Client open.");
				this.myoutbound = outbound;
				mykey = "" + System.currentTimeMillis();
				slist.put(room+"::"+mykey, this);
				System.out.println("slist size:" + slist.size());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onClose(int status) {
			System.out.println("websocket Close."+mykey);
			slist.remove(mykey);
		}

		@Override
		protected void onTextMessage(CharBuffer message) throws IOException {
			System.out.println("onTextMessage-------->");
			for (Map.Entry entry : slist.entrySet()) {
				String socketroom=entry.getKey().split("::")[0];
				String socketkey=entry.getKey().split("::")[1];
				if(this.room.equals(socketroom)&&!this.mykey.equals(socketkey)){//向room相同但是不是当前websocket发送消息
					System.out.println("-------->" + message.toString());
					System.out.println("--->socketroom:"+socketroom+",socketkey:"+socketkey);
					MyMessageInbound mmib = (MyMessageInbound) entry.getValue();
					CharBuffer buffer = CharBuffer.wrap(message);
					mmib.myoutbound.writeTextMessage(buffer);
					mmib.myoutbound.flush();
				}
			}
		}

		@Override
		protected void onBinaryMessage(ByteBuffer arg0) throws IOException {

		}
	}

}


web.xml中:
配置websocket的servlet

      room
      com.hao.RoomWebSocketServlet
    
    
      room
      /hao/room
    


jslinux中的index修改
加入datachannel和

jslinux.js增加datachannel的senddata操作
jslinux.js修改为:
/* 
   Linux launcher

   Copyright (c) 2011-2012 Fabrice Bellard

   Redistribution or commercial use is prohibited without the author's
   permission.
*/
"use strict";

var term, pc, boot_start_time, init_state;

function term_start()
{
    term = new Term(80, 130, term_handler);

    term.open();
}

/* send chars to the serial port */
function term_handler(str)
{
    pc.serial.send_chars(str);
}
console.log("hao:version 1.2")
function clipboard_set(val)
{
	console.log("hao:clipboard_set---sendData->");
	
    var el;
    el = document.getElementById("text_clipboard");
    el.value = val;
    sendData();
}

function clipboard_get()
{
	console.log("hao:clipboard_get---->");
    var el;
    el = document.getElementById("text_clipboard");
    return el.value;
}

function clear_clipboard()
{
    var el;
    el = document.getElementById("text_clipboard");
    el.value = "";
}

/* just used to display the boot time in the VM */
function get_boot_time()
{
    return (+new Date()) - boot_start_time;
}

function start()
{
    var params;
    
    init_state = new Object();

    params = new Object();

    /* serial output chars */
    params.serial_write = term.write.bind(term);

    /* memory size (in bytes) */
    params.mem_size = 16 * 1024 * 1024;

    /* clipboard I/O */
    params.clipboard_get = clipboard_get;
    params.clipboard_set = clipboard_set;

    params.get_boot_time = get_boot_time;

    /* IDE drive. The raw disk image is split into files of
     * 'block_size' KB. 
     */
    params.hda = { url: "bin/hda%d.bin", block_size: 64, nb_blocks: 912 };
    
    pc = new PCEmulator(params);

    init_state.params = params;

    //pc.load_binary("vmlinux-2.6.20.bin", 0x00100000, start2);
    pc.load_binary("vmlinux26.bin", 0x00100000, start2);
//    pc.load_binary("vmlinuxtest.bin", 0x00100000, start2);
    //pc.load_binary("vmlinuxnono.bin", 0x00100000, start2);
    //pc.load_binary("vmlinux319.bin", 0x00100000, start2);
    //pc.load_binary("vmlinux319clip.bin", 0x00100000, start2);
}

function start2(ret)
{
    if (ret < 0)
        return;
    init_state.start_addr = 0x10000;
    //pc.load_binary("linuxstartnew.bin", init_state.start_addr, start3);
    pc.load_binary("linuxstart.bin", init_state.start_addr, start3);
}

function start3(ret)
{
    var block_list;
    if (ret < 0)
        return;
    /* Preload blocks so that the boot time does not depend on the
     * time to load the required disk data (optional) */
    block_list = [ 0, 7, 3, 643, 720, 256, 336, 644, 781, 387, 464, 475, 131, 589, 468, 472, 474, 776, 777, 778, 779, 465, 466, 473, 467, 469, 470, 512, 592, 471, 691, 697, 708, 792, 775, 769 ];
    pc.ide0.drives[0].bs.preload(block_list, start4);
}

function start4(ret)
{
    var cmdline_addr;

    if (ret < 0)
        return;

    /* set the Linux kernel command line */
    cmdline_addr = 0xf800;
    pc.cpu.write_string(cmdline_addr, "console=ttyS0 root=/dev/hda ro init=/sbin/init notsc=1 hdb=none");

    pc.cpu.eip = init_state.start_addr;
    pc.cpu.regs[0] = init_state.params.mem_size; /* eax */
    pc.cpu.regs[3] = 0; /* ebx = initrd_size (no longer used) */
    pc.cpu.regs[1] = cmdline_addr; /* ecx */

    boot_start_time = (+new Date());

    pc.start();
}

term_start();


其中websocket放在aws上会有
Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING State.
的错误
参考
http://stackoverflow.com/questions/23898477/tornado-websockets-invalidstateerror-still-in-connecting-state


测试的时候
http://killinux.com/jslinux/?r=5555

http://killinux.com/jslinux/?r=5555&c=true

打开两个网页,r为room号,任意起,两个页面相同即可

然后在一个页面的jslinux中
tail -f /dev/clipboard
echo sssssssssss >/dev/clipboard

具体代码
https://github.com/killinux/rtclinux

微博: http://weibo.com/killinux
  • webrtc学习笔记9(datachannel在jslinux的应用,java版本)_第2张图片
  • 大小: 119 KB
  • 查看图片附件

你可能感兴趣的:(webrtc,websocket,jslinux,linux)