Categories
discuss

Spring: send message to websocket clients

I’m building a webchat with Spring Boot, RabbitMQ and WebSocket as POC, but I’m stucked a the last point: WebSockets
I want my ws clients to connect to a specific endpoint, like /room/{id} and when a new message arrives, I want the server to send the response to clients, but I searched for something similar and didn’t found.

Currently, when the message arrives, I process it with RabbitMQ, like

container.setMessageListener(new MessageListenerAdapter(){
            @Override
            public void onMessage(org.springframework.amqp.core.Message message, Channel channel) throws Exception {
                log.info(message);
                log.info("Got: "+ new String(message.getBody()));
            }
        });

what I would like is, instead log it , I want to send it to the client, for example: websocketManager.sendMessage(new String(message.getBody()))

Answer

Ok, I think I got it, for everyone who needs it, here is the answer:

first, you need to add WS dependencies to the pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
</dependency>

create a WS endpoint

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // the endpoint for websocket connections
        registry.addEndpoint("/stomp").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/");

        // use the /app prefix for others
        config.setApplicationDestinationPrefixes("/app");
    }

}

Note: I’m using STOMP, so the clients should connect like this

<script type="text/javascript">
    $(document).ready(function() {
        var messageList = $("#messages");
        // defined a connection to a new socket endpoint
        var socket = new SockJS('/stomp');
        var stompClient = Stomp.over(socket);
        stompClient.connect({ }, function(frame) {
            // subscribe to the /topic/message endpoint
            stompClient.subscribe("/room.2", function(data) {
                var message = data.body;
                messageList.append("<li>" + message + "</li>");
            });

        });
    });
</script>

Then, you can simply wire the ws messenger on your components with

@Autowired
private SimpMessagingTemplate webSocket;

and send the message with

webSocket.convertAndSend(channel, new String(message.getBody()));
Categories
discuss

Attempted to finish an input event but the input event receiver has already been disposed

I am trying out a Tutorial i saw online,The app Gets and displays JSONfeed from server,this part works correctly,i am trying to display this feed in Custom listview but when i try to do so i get the “Attempted to finish an input event but the input event receiver has already been disposed” error in logcat and nothing happens in app,i have an adpter class:

public class UserAdapter extends ArrayAdapter<UserData>{

    private Context context;
    private List<UserData> users_list;

    public UserAdapter(Context context, int resource,List<UserData> objects) {
        super(context, resource);
        this.context= context;
        this.users_list= objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View customview= inflater.inflate(R.layout.item_user, parent, false);

        UserData userData=  users_list.get(position);
        TextView tv = (TextView) customview.findViewById(R.id.textview1);
        tv.setText(userData.getName());

        return customview;
    }
}

My MainAtivity:

import android.app.ListActivity;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;

import android.view.Menu;
import android.view.MenuItem;

import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends ListActivity  {



    List<MyTask> tasks;

    List<UserData> userDataList;


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);

        userDataList= new ArrayList<>();

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {


        int id = item.getItemId();


        if (id == R.id.ac) {

            if (isOnline()) {
                requestData("http://192.168.1.4/database/getInfoDroid.php");

            } else {
                Toast.makeText(MainActivity.this, "Network Unavailable", Toast.LENGTH_LONG).show();
            }


            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void requestData(String uri) {
        MyTask task=new MyTask();
        task.execute(uri);
    }

    protected void updateDisplay(){
      UserAdapter adapter= new UserAdapter(this,R.layout.item_user,userDataList);
        setListAdapter(adapter);

    }

    protected boolean isOnline(){
        ConnectivityManager cm= (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo netinfo= cm.getActiveNetworkInfo();
        if(netinfo!= null && netinfo.isConnectedOrConnecting()){
            return true;
        }
        else {
            return false;
        }



    }


    private class MyTask extends AsyncTask {

        @Override
        protected void onPreExecute() {


        }


        @Override
        protected Object doInBackground(Object[] objects) {

            System.out.print("Do in background ");

            String content =HttpManager.getData(objects[0].toString());
            System.out.print(content);
            return content;


        }

        @Override
        protected void onPostExecute(Object o) {


            if (o.toString()==null){
                Toast.makeText(MainActivity.this,"Cant connect to Web",Toast.LENGTH_LONG).show();
            }


            userDataList= UserDataJsonParser.parseFeed(o.toString());
            System.out.print(userDataList);
            updateDisplay();

        }


        @Override
        protected void onProgressUpdate(Object[] values) {
            //updateDisplay(values[0].toString());
        }
    }



}

LogCat:

11-28 20:50:12.115 28063-28078/hilz.myapplication W/EGL_emulation: eglSurfaceAttrib not implemented
11-28 20:50:12.115 28063-28078/hilz.myapplication W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xa50c8260, error=EGL_SUCCESS
11-28 20:50:13.287 28063-28063/hilz.myapplication W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.

Answer

In your Public UserAdapter function, your super is not passing in the Objects.

It should be:

public UserAdapter(Context context, int resource,List<UserData> objects)
{
    super(context, resource, objects);
    this.context= context;
    this.users_list= objects;
}

and not:

public UserAdapter(Context context, int resource,List<UserData> objects)
{
    super(context, resource);
    this.context= context;
    this.users_list= objects;
}
Categories
discuss

.Net MVC how to add scripts to individual views

I was wondering if there is a way to add JavaScript files to individual views if I am using a wrapper .cshtml file.

Basically I have a wrapper cshtml file called _Layout that I am using for all my front end views. It basically has the <header> section and the HTML for my header/navigation and the footer. It also contains references to all the JavaScript files I need on each page after the footer.

However, on my contact view I want to use another JavaScript file, but I don’t want to add it to the wrapper as that will add it to every single view.

Is there anyway to get add the file to the wrapper using a conditional statement – i.e. if Contact view then reference the contact JS file?

Answer

You can use Razor’s section. It allows you to create “sections” in your layout page, and then add to them from your view pages.

You might already have a section “Scripts” declared in your layout page. If not, all you need to do is add @RenderSection("Scripts", required: false) in your layout, immediately after your other script tags. This creates a section called “Scripts” which we will add to later.

Then, you can add to that section by adding the following to your individual views:

@section Scripts {
    <script type="text/javascript" src="..."></script>
}

You can do this with other elements as well; you aren’t limited only to scripts. You’ll just have to add another @RenderSection("SectionName", required: false) to your layout page.

You might also be interested in reading Scott Gu’s slightly dated (2010) blog post on Layouts and Sections with Razor.

Categories
discuss

Nodejs modules not working as expected in different devices

I am using twitter streaming api & johnny-five with some other modules http , express& socket.io with arduino uno

My script is working fine in laptop. But my production will be on a tablet. I have two tablets and both are responding differently. On hp omni tablet i am receiving following error

enter image description here

Also i have arduino-uno connected on port COM3 but its shows device connected on COM1

As far as i know this error is caused when standard firmata is not uploded in arduino. I have uploaded this program and it work fine in laptop

On Acer Tablet i am not receiving any errors program starts perfectly fine without any issues but i am not receiving tweets with twitter streaming api

I have crossed checked many times it runs perfectly fine on laptop every time i run it but gives two different issues with the tablets

Here is the code i am using

var Twitter = require('twitter');
var five = require("johnny-five");
var express = require('express')
  , app = express()
  , http = require('http')
  , server = http.createServer(app)  
  , io = require('socket.io').listen(server);

server.listen(8080);

// routing
app.use(express.static(__dirname + '/http'));
app.use(function (req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', "http://"+req.headers.host+':80');

        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
        next();
    }
);

var client = new Twitter({
  consumer_key: 'abc',
  consumer_secret: 'abc',
  access_token_key: 'abc',
  access_token_secret: 'abc'
});

var board = new five.Board();

board.on("ready", function() {
    this.pinMode(5, five.Pin.OUTPUT);
    this.pinMode(10, five.Pin.INPUT);
      //Ask to visit url
      console.log("Visit http://localhost:8080");
    var randomHashtag = Math.floor((Math.random() * 10000) +1);
    var count = 0;//Initialize counter
    io.sockets.on('connection', function (socket) {     
        console.log('Ready to recieve tweets');//Prints Message when Socket.io is ready to recieve tweets
        io.emit('stream',{number:randomHashtag});//Send random no when socket initzilize
        client.stream('statuses/filter', {track: '#tweetMe'}, function(stream) {
            stream.on('data', function(tweet) {
                if(tweet.text.search(randomHashtag) > 0){
                    count++;//Increment pending tweets              
                    randomHashtag  = Math.floor((Math.random() * 10000) +1);                
                    io.emit('stream',{number:randomHashtag});                   
                    board.digitalWrite(5,1);
                    console.log(tweet.text);                    
                }
                else{
                    console.log("Tweet Without random No");
                }
            });

        stream.on('error', function(error) {
            throw error;
        });
        });
    });
});

Answer

I resolved issue with HP OMNI tablet by manually telling johnny-five on which port my arduino is connected as mentioned in OFFICIAL DOCUMENTATION

new five.Board({ port: "COM3" });//FOR WINDOWS ONLY

Also i had to reinstall all modules to make it work

(Still not working with Acer tablet though)

Categories
discuss

Apache commons csv skip lines

How to skip lines in input file with apache commons csv. In my file first few lines are garbage useful meta-information like date, etc. Can’t find any options for this.

private void parse() throws Exception {
    Iterable<CSVRecord> records = CSVFormat.EXCEL
            .withQuote('"').withDelimiter(';').parse(new FileReader("example.csv"));
    for (CSVRecord csvRecord : records) {
        //do something            
    }
}

Answer

Use FileReader.readLine() before starting the for-loop.

Your example:

private void parse() throws Exception {
  FileReader reader = new FileReader("example.csv");
  reader.readLine(); // Read the first/current line.

  Iterable <CSVRecord> records = CSVFormat.EXCEL.withQuote('"').withDelimiter(';').parse(reader);
  for (CSVRecord csvRecord: records) {
    // do something
  }
}
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..