手记

Android服务器微架构

public class MainActivity extends AppCompatActivity {

    private SimpleHttpServer shs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //设置端口与最大监听数
        WebConfiguration wed = new WebConfiguration(8078, 50);
        shs = new SimpleHttpServer(wed);
        //注册路由
        shs.reqisterResourceHandler(new UploadImageHandler());
        shs.reqisterResourceHandler(newResourceInAssetsHandler(MainActivity.this));
        //启动服务器
        shs.startAsync();

    }

    @Override
    protected void onDestroy() {
        try {
            shs.stopAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
}
class WebConfiguration {
    /**
     * 端口号
     */
    private int port;
    /**
     * 最大监听数
     */
    private int maxParallels;
    public WebConfiguration(int port,int maxParallels){
        this.port=port;
        this.maxParallels=maxParallels;
    }
    public void setPort(int port){
        this.port=port;
    }
    public void setMaxParallels(int maxParallels){
        this.maxParallels=maxParallels;
    }
    public int getPort(){
        return this.port;
    }
    public int getMaxParallels(){
        return this.maxParallels;
    }
}
public class SimpleHttpServer {
    private final ExecutorService threadPoob;
    private boolean isEnable;
    private WebConfiguration web;
    private ServerSocket socket;
    private Socket remotePeer;
    private Set<IResourceUriHandler> resourceHandler;

    public SimpleHttpServer(WebConfiguration  web){
        this.web=web;
       /**
         * 在构造里创建线程池与Set集合
         * Set集合存储路由
         * 线程池对Socket操作
         */
        threadPoob = Executors.newCachedThreadPool();
        resourceHandler=new HashSet<>();
    }
     /**
     * Android对耗时操作都得异步执行
     */
    public void startAsync(){
        isEnable=true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                doProcSync();
            }
        }).start();
    }
    public void stopAsync() throws IOException {
        if(!isEnable){
            return;
        }
        isEnable=false;
        if(socket!=null){
            socket.close();
            socket=null;
        }
    }

    private void doProcSync() {

        try {
            InetSocketAddress socketaddress=new InetSocketAddress(web.getPort());
            socket=new ServerSocket();
            /**
             * 绑定端口号
             */
            socket.bind(socketaddress);
            while (isEnable){
                /**
                 * 阻塞,等待客户端
                 */
                remotePeer = socket.accept();
                /**
                 * 扔到线程池
                 */
                threadPoob.submit(new Runnable() {
                    @Override
                    public void run() {
                        onAcceptRemotePeer(remotePeer);

                    }
                });
            }
        } catch (IOException e) {
            Log.e("doProcSync",e.toString());
            e.printStackTrace();
        }
    }

    private void onAcceptRemotePeer(Socket remotePeer) {
        try {
            /**
             * HttpConntext 存储Socket的请求信息与Scoket
             */
            HttpConntext httpConntext=new HttpConntext();
            httpConntext.setUnderlySocke(remotePeer);
            /**
             * 读取请求信息
             */
            InputStream inputStream = remotePeer.getInputStream();
            String headerLine=null;
            String resourceUri=headerLine=StreamToolkit.reabLing(inputStream).split(" ")[1];
            Log.e("spy",resourceUri);
            while ((headerLine=StreamToolkit.reabLing(inputStream))!=null) {
                if (headerLine.equals("\r\n")) {
                    break;
                }
                Log.e("spy", headerLine);
                String[] requestheader=headerLine.split(":");
                httpConntext.addRequestHeader(requestheader[0],requestheader[1]);
            }
            /**
             * 遍历路由
             */
            for(IResourceUriHandler handler:resourceHandler){
                if(!handler.accept(resourceUri)){
                    continue;
                }
                handler.handle(resourceUri,httpConntext);
            }
        } catch (IOException e) {
            Log.e("onAcceptRemotePeer",e.toString());
        }
    }
     /**
     *路由添加到Set
     */
    public void reqisterResourceHandler(IResourceUriHandler iResourceUriHandler){
        resourceHandler.add(iResourceUriHandler);
    }
}
class StreamToolkit {
    /**
     *工具类
     */
    public static String reabLing(InputStream inputStream) throws IOException {
        int c1=0;
        int c2=0;
        StringBuilder sb=new StringBuilder();
        while (c2!=-1&&!(c1=='\r'&&c2=='\n')){
            c1=c2;
            c2=inputStream.read();
            sb.append((char) c2);
        }
        if(sb.length()==0){
            return null;
        }
        return sb.toString();
    }

    public static byte[] readRawFromStream(InputStream open) throws IOException {
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        byte b[]=new byte[10240];
        int nReade;
        while((nReade=open.read(b))!=-1){
            bos.write(b,0,nReade);
        }
        return bos.toByteArray();
    }
}
public class HttpConntext {
    private Socket underlySocke;
    private HashMap hashMap;
    public HttpConntext(){
        this.hashMap=new HashMap<String,String>();
    }
    public void setUnderlySocke(Socket underlySocke) {
        this.underlySocke = underlySocke;
    }
    public Socket getUnderlySocke(){
        return this.underlySocke;
    }
    public void addRequestHeader(String headerName,String headerValue){
        this.hashMap.put(headerName,headerValue);
    }
    public String getRequstHeaderValue(String headerName){
        return (String) this.hashMap.get(headerName);
    }
}
public interface IResourceUriHandler {  //路由模板
    boolean accept(String uri);
    void handle(String uri,HttpConntext httpConntext) throws IOException;
}
public class ResourceInAssetsHandler implements IResourceUriHandler {
    private Context context;
    private String acceptPrefix="/static/";
    public ResourceInAssetsHandler(Context context){
        this.context=context;
    }
    @Override
    public boolean accept(String uri) {
        boolean b=uri.startsWith(acceptPrefix);
        Log.e("accept:"+b,acceptPrefix);
        return b;

    }

    @Override
    public void handle(String uri, HttpConntext httpConntext) throws IOException {
        int startIndex=acceptPrefix.length();
        String assetsPath=uri.substring(startIndex);
        InputStream open = context.getAssets().open(assetsPath);
        byte[] raw=StreamToolkit.readRawFromStream(open);
        open.close();
        OutputStream outputStream = httpConntext.getUnderlySocke().getOutputStream();
        PrintStream printStream=new PrintStream(outputStream);
        printStream.println("HTTP/1.1 200 OK");
        printStream.println("Content-Length:"+raw.length);
        if (assetsPath.endsWith(".html")){
            printStream.println("Context-Type:text/html");
        }else if(assetsPath.endsWith(".js")){
            printStream.println("Context-Type:text/js");
        }else if(assetsPath.endsWith(".css")){
            printStream.println("Context-Type:text/css");
        }else if (assetsPath.endsWith(".jpg")){
            printStream.println("Context-Type:text/jpg");
        }else if(assetsPath.endsWith(".png")){
            printStream.println("Context-Type:text/png");
        }
        printStream.println();//表示头部数据写完
        printStream.write(raw);
        printStream.flush();
        printStream.close();
    }
}
2人推荐
随时随地看视频
慕课网APP