diff --git a/Cargo.toml b/Cargo.toml
index 3364f83970245f55cf8c5f9e026f1f42a01976d2..860fd47c6e5b1c4bcef2a22847e7ae13a024193a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,8 +10,6 @@ edition = "2018"
 wasm-bindgen = "0.2"
 js-sys = "0.3"
 log = "0.4.11"
-console_log = "0.2.0"
-console_error_panic_hook = "0.1.6"
 
 [dependencies.web-sys]
 version = "0.3.22"
@@ -24,3 +22,7 @@ features = [
   "ProgressEvent",
   "WebSocket",
 ]
+
+[dev-dependencies]
+console_log = "0.2.0"
+console_error_panic_hook = "0.1.6"
diff --git a/examples/basic.rs b/examples/basic.rs
index a5b9251632b4dbe1dba9ed2c44cc5a07f6adb9eb..ea1c387c279607511b198700b6d9744e0898ff94 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -11,7 +11,7 @@ fn main() -> Result<(), JsValue> {
     console_log::init_with_level(Level::Trace).expect("Failed to enable logging");
     info!("Creating connection");
 
-    let mut client = wasm_sockets::EventClient::new("ws://localhost:9001")?;
+    let mut client = wasm_sockets::EventClient::new("wss://echo.websocket.org")?;
     client.set_on_error(Some(Box::new(|e| {
         error!("{:#?}", e);
     })));
@@ -21,6 +21,13 @@ fn main() -> Result<(), JsValue> {
             info!("{:#?}", &c.borrow_mut().status);
             info!("Sending message...");
             c.borrow().send_string("test...").unwrap();
+            c.borrow().send_binary(vec![20]).unwrap();
+        },
+    )));
+
+    client.set_on_message(Some(Box::new(
+        |c: Rc<RefCell<wasm_sockets::EventClient>>, e: wasm_sockets::Message| {
+            info!("New Message: {:#?}", e);
         },
     )));
 
diff --git a/src/lib.rs b/src/lib.rs
index 17a6e4e0c892a95854ae9a4f988b5b32cef5c0df..be07c61f5c7dd9e9f22c64ec37b97692fc13ce75 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -84,10 +84,10 @@ pub enum ConnectionStatus {
     Connected,
     Error(ErrorEvent),
 }
-
 #[derive(Debug)]
 pub enum Message {
     Text(String),
+    Binary(Vec<u8>),
 }
 pub struct BlockingClient {
     pub url: String,
@@ -129,6 +129,7 @@ pub struct EventClient {
     pub status: Rc<RefCell<ConnectionStatus>>,
     pub on_error: Rc<RefCell<Option<Box<dyn Fn(ErrorEvent) -> ()>>>>,
     pub on_connection: Rc<RefCell<Option<Box<dyn Fn(Rc<RefCell<EventClient>>, JsValue) -> ()>>>>,
+    pub on_message: Rc<RefCell<Option<Box<dyn Fn(Rc<RefCell<EventClient>>, Message) -> ()>>>>,
 }
 impl EventClient {
     pub fn new(url: &str) -> Result<Self, JsValue> {
@@ -158,23 +159,29 @@ impl EventClient {
         > = Rc::new(RefCell::new(None));
         let on_connection_ref = on_connection.clone();
 
+        let on_message: Rc<RefCell<Option<Box<dyn Fn(Rc<RefCell<EventClient>>, Message) -> ()>>>> =
+            Rc::new(RefCell::new(None));
+        let on_message_ref = on_message.clone();
+
         let ref_status = status.clone();
 
         let connection = Rc::new(RefCell::new(ws));
         let connection_ref = connection.clone();
 
-        let test = Rc::new(RefCell::new(Self {
+        let client = Rc::new(RefCell::new(Self {
             url: Rc::new(RefCell::new(url.to_string())),
             connection: connection.clone(),
             on_error: on_error.clone(),
             on_connection: on_connection.clone(),
             status: status.clone(),
+            on_message: on_message.clone(),
         }));
+        let client_ref = client.clone();
 
         let onopen_callback = Closure::wrap(Box::new(move |v| {
             *ref_status.borrow_mut() = ConnectionStatus::Connected;
             if let Some(f) = &*on_connection_ref.borrow() {
-                f.as_ref()(test.clone(), v);
+                f.as_ref()(client_ref.clone(), v);
             }
         }) as Box<dyn FnMut(JsValue)>);
         connection
@@ -182,11 +189,59 @@ impl EventClient {
             .set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
         onopen_callback.forget();
 
+        let client_ref = client.clone();
+        let client_ref2 = client.clone();
+
+        let onmessage_callback = Closure::wrap(Box::new(move |e: MessageEvent| {
+            // Process different types of message data
+            if let Ok(abuf) = e.data().dyn_into::<js_sys::ArrayBuffer>() {
+                // Received arraybuffer
+                trace!("message event, received arraybuffer: {:?}", abuf);
+                // Convert arraybuffer to vec
+                let array = js_sys::Uint8Array::new(&abuf).to_vec();
+                if let Some(f) = &*on_message_ref.borrow() {
+                    f.as_ref()(client_ref.clone(), Message::Binary(array));
+                }
+            } else if let Ok(blob) = e.data().dyn_into::<web_sys::Blob>() {
+                // Received blob data
+                trace!("message event, received blob: {:?}", blob);
+                let fr = web_sys::FileReader::new().unwrap();
+                let fr_c = fr.clone();
+                // create onLoadEnd callback
+                let cbref = on_message_ref.clone();
+                let cbfref = client_ref.clone();
+                let onloadend_cb = Closure::wrap(Box::new(move |_e: web_sys::ProgressEvent| {
+                    let array = js_sys::Uint8Array::new(&fr_c.result().unwrap()).to_vec();
+                    if let Some(f) = &*cbref.borrow() {
+                        f.as_ref()(cbfref.clone(), Message::Binary(array));
+                    }
+                })
+                    as Box<dyn FnMut(web_sys::ProgressEvent)>);
+                fr.set_onloadend(Some(onloadend_cb.as_ref().unchecked_ref()));
+                fr.read_as_array_buffer(&blob).expect("blob not readable");
+                onloadend_cb.forget();
+            } else if let Ok(txt) = e.data().dyn_into::<js_sys::JsString>() {
+                if let Some(f) = &*on_message_ref.borrow() {
+                    f.as_ref()(client_ref.clone(), Message::Text(txt.into()));
+                }
+            } else {
+                // Got unknown data
+                panic!("Unknown data: {:#?}", e.data());
+            }
+        }) as Box<dyn FnMut(MessageEvent)>);
+        // set message event handler on WebSocket
+        connection
+            .borrow()
+            .set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
+        // forget the callback to keep it alive
+        onmessage_callback.forget();
+
         Ok(Self {
             url: Rc::new(RefCell::new(url.to_string())),
             connection,
             on_error,
             on_connection,
+            on_message,
             status: status,
         })
     }
@@ -201,7 +256,20 @@ impl EventClient {
         *self.on_connection.borrow_mut() = f;
     }
 
+    pub fn set_on_message(
+        &mut self,
+        f: Option<Box<dyn Fn(Rc<RefCell<EventClient>>, Message) -> ()>>,
+    ) {
+        *self.on_message.borrow_mut() = f;
+    }
+
     pub fn send_string(&self, message: &str) -> Result<(), JsValue> {
         self.connection.borrow_mut().send_with_str(message)
     }
+
+    pub fn send_binary(&self, message: Vec<u8>) -> Result<(), JsValue> {
+        self.connection
+            .borrow_mut()
+            .send_with_u8_array(message.as_slice())
+    }
 }